Changeset 71538 in webkit
- Timestamp:
- Nov 8, 2010 10:04:58 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r71537 r71538 1 2010-11-08 Noam Rosenthal <noam.rosenthal@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 [Texmap] [Qt] Texture mapper initial implementation 6 https://bugs.webkit.org/show_bug.cgi?id=47070 7 8 Added a test that includes several composited layers, containing pixel data that's larger 9 than 24MB, which is the default value for TextureMapper's cache. This tests the video memory 10 ceiling functionality of TextureMapper, as purging that cache would kick in whe running this test. 11 12 * compositing/layer-creation/many-layers.html: Added. 13 1 14 2010-11-08 Tony Chang <tony@chromium.org> 2 15 -
trunk/WebCore/ChangeLog
r71536 r71538 1 2010-11-08 Noam Rosenthal <noam.rosenthal@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 [Texmap] [Qt] Texture mapper initial implementation 6 https://bugs.webkit.org/show_bug.cgi?id=47070 7 8 Make the necessary changes in TextureMapperNode in preparation of making it possible to paint it 9 from a different thread. 10 The main problematic part was the cache, which made it so that textures can become invalid and have to 11 be rerendered from content during paint. This is solved here by creating a pack/unpack function for 12 textures, which lets a texture archive its data away from video memory, or do whatever the platform 13 thinks is right for freeing memory without needing to re-render again from content (which cannot be 14 made thread safe). 15 16 After this change, TextureMapperNode moved to its own file, and has 2 entry points: paint and syncCompositingState. 17 The idea is that syncCompositingState has to be called in the UI thread, paint can be called from a different 18 thread, and they should block each other. 19 20 The new test tests the cache code-path, to show that the pack/unpack technique works for cases where it 21 kicks in. 22 23 Test: compositing/layer-creation/many-layers.html 24 25 * WebCore.pro: 26 * platform/graphics/opengl/TextureMapperGL.cpp: 27 (WebCore::BitmapTextureGL::~BitmapTextureGL): 28 (WebCore::BitmapTextureGL::BitmapTextureGL): 29 (WebCore::TextureMapperGL::TextureMapperGL): 30 (WebCore::TextureMapperGL::drawTexture): 31 * platform/graphics/opengl/TextureMapperGL.h: 32 (WebCore::TextureMapperGL::create): 33 * platform/graphics/qt/TextureMapperQt.cpp: 34 (WebCore::BitmapTextureQt::pack): 35 (WebCore::BitmapTextureQt::unpack): 36 (WebCore::TextureMapper::create): 37 (WebCore::BitmapTextureQt::BitmapTextureQt): 38 * platform/graphics/qt/TextureMapperQt.h: Added. 39 1 40 2010-11-08 Simon Fraser <simon.fraser@apple.com> 2 41 -
trunk/WebCore/WebCore.pro
r71515 r71538 3858 3858 DEFINES += WTF_USE_TEXTURE_MAPPER=1 3859 3859 HEADERS += \ 3860 platform/graphics/qt/TextureMapperQt.h \ 3861 platform/graphics/texmap/GraphicsLayerTextureMapper.h \ 3860 3862 platform/graphics/texmap/TextureMapper.h \ 3863 platform/graphics/texmap/TextureMapperNode.h \ 3861 3864 platform/graphics/texmap/TextureMapperPlatformLayer.h 3862 3865 3863 3866 SOURCES += \ 3864 3867 platform/graphics/qt/TextureMapperQt.cpp \ 3868 platform/graphics/texmap/TextureMapperNode.cpp \ 3865 3869 platform/graphics/texmap/GraphicsLayerTextureMapper.cpp 3866 3870 -
trunk/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
r71213 r71538 230 230 virtual void endPaint(); 231 231 virtual void setContentsToImage(Image*); 232 ~BitmapTextureGL() { destroy(); } 232 233 233 234 private: … … 242 243 IntSize m_actualSize; 243 244 bool m_surfaceNeedsReset; 244 RefPtr<TextureMapperGL>m_textureMapper;245 TextureMapperGL* m_textureMapper; 245 246 BitmapTextureGL() 246 247 : m_id(0) … … 249 250 , m_fbo(0) 250 251 , m_surfaceNeedsReset(true) 252 , m_textureMapper(0) 251 253 { 252 254 } … … 266 268 { 267 269 static bool shadersCompiled = false; 270 obtainCurrentContext(); 268 271 if (shadersCompiled) 269 272 return; … … 417 420 0, 0, 1, 0, 418 421 0, 0, 0, 1}; 419 glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask);422 GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask)); 420 423 GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::MaskTextureVariable], 1)) 421 424 GL_CMD(glActiveTexture(GL_TEXTURE0)) 422 425 } 423 424 426 425 427 if (textureGL.m_opaque && opacity > 0.99 && !maskTexture) … … 432 434 GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)) 433 435 } 434 435 436 436 437 const char* TextureMapperGL::type() const -
trunk/WebCore/platform/graphics/opengl/TextureMapperGL.h
r71213 r71538 48 48 void obtainCurrentContext(); 49 49 bool makeContextCurrent(); 50 static PassOwnPtr<TextureMapperGL> create() 51 { 52 return new TextureMapperGL; 53 } 50 54 51 55 private: -
trunk/WebCore/platform/graphics/qt/TextureMapperQt.cpp
r71213 r71538 19 19 20 20 #include "config.h" 21 #include " texmap/TextureMapper.h"21 #include "TextureMapperQt.h" 22 22 23 23 #include <QtCore/qdebug.h> … … 30 30 31 31 namespace WebCore { 32 33 class BitmapTextureQt : public BitmapTexture {34 friend class TextureMapperQt;35 public:36 BitmapTextureQt() {}37 virtual void destroy();38 virtual IntSize size() const { return IntSize(m_pixmap.width(), m_pixmap.height()); }39 virtual void reset(const IntSize&, bool opaque);40 virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);41 virtual void endPaint();42 virtual void setContentsToImage(Image*);43 virtual bool save(const String& path);44 virtual bool isValid() const { return !m_pixmap.isNull(); }45 virtual bool allowOfflineTextureUpload() const { return true; }46 IntRect sourceRect() const { return IntRect(0, 0, contentSize().width(), contentSize().height()); }47 private:48 QPainter m_painter;49 QPixmap m_pixmap;50 };51 52 class TextureMapperQt : public TextureMapper {53 public:54 virtual void drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture);55 virtual void bindSurface(BitmapTexture* surface);56 virtual void setClip(const IntRect&);57 virtual void setGraphicsContext(GraphicsContext*);58 virtual bool allowSurfaceForRoot() const { return false; }59 TextureMapperQt();60 virtual const char* type() const { return "TextureMapperQt"; }61 virtual PassRefPtr<BitmapTexture> createTexture();62 63 static void initialize(QPainter* painter)64 {65 painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);66 }67 68 private:69 QPainter* m_painter;70 RefPtr<BitmapTextureQt> m_currentSurface;71 };72 32 73 33 void BitmapTextureQt::destroy() … … 117 77 BitmapTexture::reset(pixmap->size(), !pixmap->hasAlphaChannel()); 118 78 m_pixmap = *pixmap; 79 } 80 81 void BitmapTextureQt::pack() 82 { 83 if (m_pixmap.isNull()) 84 return; 85 86 m_image = m_pixmap.toImage(); 87 m_pixmap = QPixmap(); 88 m_isPacked = true; 89 } 90 91 void BitmapTextureQt::unpack() 92 { 93 m_isPacked = false; 94 if (m_image.isNull()) 95 return; 96 97 m_pixmap = QPixmap::fromImage(m_image); 98 m_image = QImage(); 119 99 } 120 100 … … 183 163 } 184 164 185 Pass RefPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)165 PassOwnPtr<TextureMapper> TextureMapper::create(GraphicsContext* context) 186 166 { 187 167 #ifdef QT_OPENGL_LIB 188 if (context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2) { 189 TextureMapperGL* texmapGL = new TextureMapperGL; 190 return adoptRef(texmapGL); 191 } 168 if (context && context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2) 169 return new TextureMapperGL; 192 170 #endif 193 return adoptRef(new TextureMapperQt); 194 } 195 171 return new TextureMapperQt; 172 } 196 173 197 174 PassRefPtr<BitmapTexture> TextureMapperQt::createTexture() 198 175 { 199 176 return adoptRef(new BitmapTextureQt()); 177 } 178 179 BitmapTextureQt::BitmapTextureQt() 180 : m_isPacked(false) 181 { 182 200 183 } 201 184 -
trunk/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
r71213 r71538 21 21 #include "GraphicsLayerTextureMapper.h" 22 22 23 #include "CurrentTime.h" 24 #include "FloatRect.h" 25 #include "GraphicsContext.h" 26 #include "HashMap.h" 27 #include "Image.h" 28 #include "RefCounted.h" 29 #include "TextureMapper.h" 30 #include "TextureMapperPlatformLayer.h" 31 #include "Timer.h" 32 #include "TransformOperations.h" 33 #include "TranslateTransformOperation.h" 34 #include "UnitBezier.h" 35 36 #define DEBUG_TEXMAP_FPS 0 23 #include "TextureMapperNode.h" 37 24 38 25 namespace WebCore { 39 26 40 struct TexmapPaintOptions { 41 BitmapTexture* surface; 42 TextureMapper* textureMapper; 43 TextureMapperNode* rootLayer; 44 float opacity; 45 IntRect scissorRect; 46 IntRect visibleRect; 47 bool isSurface; 48 }; 49 class TextureMapperCache { 50 public: 51 void mark(BitmapTexture* texture); 52 53 class Entry { 54 public: 55 RefPtr<BitmapTexture> texture; 56 Entry() : previousCost(0) { } 57 inline int calculateCost() const 58 { 59 if (!texture || !texture->isValid()) 60 return 0; 61 const IntSize textureSize = texture->size(); 62 // an image's cost in bytes is width * height * bytes per pixel (4). 63 return textureSize.width() * textureSize.height() * 4; 64 } 65 Entry(BitmapTexture* newTexture) 66 : texture(newTexture) 67 { 68 } 69 bool operator==(const Entry& other) const { return texture == other.texture; } 70 int previousCost; 71 }; 72 73 TextureMapperCache() : m_totalCost(0) {} 74 75 void purge(); 76 Vector<Entry> m_data; 77 int m_totalCost; 78 #ifndef TEXMAP_TEXTURE_CACHE_KBS 79 #define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024 80 #endif 81 static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024; 82 static const int PurgeAmount = MaxCost / 4; 83 }; 84 85 86 void TextureMapperCache::purge() 87 { 88 // If this is in the GL implementation, we need an active GL context, because we might call glDeleteTextures. 89 const int size = m_data.size(); 90 91 if (m_totalCost <= TextureMapperCache::MaxCost) 92 return; 93 94 // Ensure that we have the right count. It might be inaccurate if content changed size. 95 // We only do this when we're actually ready to purge. 96 m_totalCost = 0; 97 for (int i = 0; i < size; ++i) 98 m_totalCost += m_data[i].calculateCost(); 99 100 for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) { 101 Entry& entry = m_data[i]; 102 if (entry.texture->isLocked() || !entry.texture->isValid()) 103 continue; 104 m_totalCost -= entry.previousCost; 105 entry.texture->destroy(); 106 m_data.remove(i); 107 } 108 } 109 110 void TextureMapperCache::mark(BitmapTexture* texture) 111 { 112 if (!texture || !texture->isValid()) 113 return; 114 115 Entry entry(texture); 116 size_t index = m_data.find(entry); 117 if (!index) 118 return; 119 120 if (index < m_data.size()) 121 m_data.remove(index); 122 const int cost = entry.calculateCost(); 123 m_totalCost -= entry.previousCost; 124 m_totalCost += (entry.previousCost = cost); 125 m_data.prepend(entry); 126 } 127 128 TextureMapperCache gTextureMapperCache; 129 130 class TextureMapperCacheLock { 131 public: 132 TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture) 133 { 134 if (m_texture) 135 m_texture->lock(); 136 } 137 ~TextureMapperCacheLock() 138 { 139 if (m_texture) 140 m_texture->unlock(); 141 } 142 143 private: 144 RefPtr<BitmapTexture> m_texture; 145 }; 146 147 class TextureMapperNode : public TextureMapperContentLayer { 148 149 public: 150 // This set of flags help us defer which properties of the layer have been 151 // modified by the compositor, so we can know what to look for in the next flush. 152 enum ChangeMask { 153 NoChanges = 0, 154 155 ParentChange = (1L << 0), 156 ChildrenChange = (1L << 1), 157 MaskLayerChange = (1L << 2), 158 PositionChange = (1L << 3), 159 160 AnchorPointChange = (1L << 4), 161 SizeChange = (1L << 5), 162 TransformChange = (1L << 6), 163 ContentChange = (1L << 7), 164 165 ContentsOrientationChange = (1L << 9), 166 OpacityChange = (1L << 10), 167 ContentsRectChange = (1L << 11), 168 169 Preserves3DChange = (1L << 12), 170 MasksToBoundsChange = (1L << 13), 171 DrawsContentChange = (1L << 14), 172 ContentsOpaqueChange = (1L << 15), 173 174 BackfaceVisibilityChange = (1L << 16), 175 ChildrenTransformChange = (1L << 17), 176 DisplayChange = (1L << 18), 177 BackgroundColorChange = (1L << 19), 178 179 ReplicaLayerChange = (1L << 20) 180 }; 181 182 // The compositor lets us special-case images and colors, so we try to do so. 183 enum StaticContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType}; 184 185 TextureMapperNode* rootLayer(); 186 187 TextureMapperNode(GraphicsLayerTextureMapper* newLayer); 188 virtual ~TextureMapperNode(); 189 190 void clearDirectImage(); 191 void computeTransformations(); 192 IntSize nearestSurfaceSize() const; 193 void computeReplicaTransform(); 194 void computeLayerType(); 195 void computeLocalTransform(); 196 void flattenTo2DSpaceIfNecessary(); 197 void initializeTextureMapper(TextureMapper*); 198 void invalidateTransform(); 199 void notifyChange(ChangeMask); 200 void syncCompositingState(bool recurse); 201 void performPostSyncOperations(); 202 void setNeedsDisplay(); 203 void setNeedsDisplayInRect(IntRect); 204 virtual void cleanupTextureMapper(); 205 206 void paintRecursive(TexmapPaintOptions options); 207 void paintSelf(const TexmapPaintOptions& options); 208 void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect); 209 210 int countDescendantsWithContent() const; 211 bool hasSurfaceDescendants() const; 212 213 IntSize size() const { return m_size; } 214 215 virtual void setPlatformLayerClient(TextureMapperLayerClient*); 216 virtual void paint(TextureMapper*, const TextureMapperContentLayer::PaintOptions&); 217 218 static TextureMapperNode* toTextureMapperNode(GraphicsLayer*); 219 public: 220 GraphicsLayerTextureMapper* m_layer; 221 const char* m_lastTextureMapperType; 222 RefPtr<TextureMapper> m_lastTextureMapper; 223 struct TransformData { 224 TransformationMatrix base, target, replica, forDescendants, perspective, local; 225 IntRect targetBoundingRect; 226 float centerZ; 227 bool dirty, localDirty, perspectiveDirty; 228 IntRect boundingRectFromRoot; 229 TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { } 230 }; 231 232 TransformData m_transforms; 233 234 enum LayerType { 235 DefaultLayer, 236 RootLayer, 237 ScissorLayer, 238 ClipLayer, 239 TransparencyLayer 240 }; 241 242 LayerType m_layerType; 243 244 struct ContentData { 245 IntRect needsDisplayRect; 246 bool needsDisplay; 247 Color backgroundColor; 248 249 StaticContentType contentType; 250 RefPtr<Image> image; 251 TextureMapperVideoLayer* media; 252 253 ContentData() 254 : needsDisplay(false) 255 , contentType(HTMLContentType) 256 , image(0) 257 , media(0) 258 { 259 } 260 261 }; 262 263 inline IntRect targetRect() const 264 { 265 return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect; 266 } 267 268 inline IntRect entireRect() const 269 { 270 return IntRect(0, 0, m_size.width(), m_size.height()); 271 } 272 273 inline IntRect replicaRect() const 274 { 275 return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect(); 276 } 277 278 RefPtr<BitmapTexture> m_texture; 279 RefPtr<BitmapTexture> m_surface, m_replicaSurface; 280 281 ContentData m_pendingContent; 282 ContentData m_currentContent; 283 284 Vector<TextureMapperNode*> m_children; 285 TextureMapperNode* m_parent; 286 TextureMapperNode* m_effectTarget; 287 int m_changeMask; 288 IntSize m_size, m_nearestSurfaceSize; 289 String m_name; 290 TextureMapperLayerClient* m_platformClient; 291 292 struct State { 293 FloatPoint pos; 294 FloatPoint3D anchorPoint; 295 FloatSize size; 296 TransformationMatrix transform; 297 TransformationMatrix childrenTransform; 298 Color backgroundColor; 299 Color currentColor; 300 GraphicsLayer::CompositingCoordinatesOrientation geoOrientation; 301 GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation; 302 float opacity; 303 IntRect contentsRect; 304 int descendantsWithContent; 305 TextureMapperNode* maskLayer; 306 TextureMapperNode* replicaLayer; 307 bool preserves3D; 308 bool masksToBounds; 309 bool drawsContent; 310 bool contentsOpaque; 311 bool backfaceVisibility; 312 bool visible; 313 bool dirty; 314 bool tiled; 315 bool hasSurfaceDescendants; 316 317 State() 318 : opacity(1.f) 319 , descendantsWithContent(0) 320 , maskLayer(0) 321 , replicaLayer(0) 322 , preserves3D(false) 323 , masksToBounds(false) 324 , drawsContent(false) 325 , contentsOpaque(false) 326 , backfaceVisibility(false) 327 , visible(true) 328 , dirty(true) 329 , tiled(false) 330 , hasSurfaceDescendants(false) 331 { 332 } 333 }; 334 State m_state; 335 }; 336 337 void TextureMapperNode::setNeedsDisplayInRect(IntRect rect) 338 { 339 if (m_platformClient) { 340 if (m_state.hasSurfaceDescendants) { 341 m_platformClient->setNeedsDisplay(); 342 return; 343 } 344 rect.intersect(IntRect(0, 0, m_size.width(), m_size.height())); 345 if (rect.isEmpty()) 346 return; 347 m_platformClient->setNeedsDisplayInRect(rect); 348 return; 349 } 350 351 if (!m_parent) 352 return; 353 354 m_parent->setNeedsDisplayInRect(rect); 355 } 356 357 void TextureMapperNode::setNeedsDisplay() 358 { 359 if (m_effectTarget) 360 m_effectTarget->setNeedsDisplay(); 361 if (m_transforms.targetBoundingRect.isEmpty()) 362 return; 363 if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) 364 setNeedsDisplayInRect(m_transforms.targetBoundingRect); 365 } 366 367 368 void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client) 369 { 370 m_platformClient = client; 371 } 372 373 static int compareGraphicsLayersZValue(const void* a, const void* b) 374 { 375 typedef const TextureMapperNode* NodePtr; 376 const NodePtr* nodeA = static_cast<const NodePtr*>(a); 377 const NodePtr* nodeB = static_cast<const NodePtr*>(b); 378 return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000); 379 } 380 inline static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last) 381 { 382 qsort(array.data(), array.size(), sizeof(TextureMapperNode*), compareGraphicsLayersZValue); 383 } 384 385 bool TextureMapperNode::hasSurfaceDescendants() const 386 { 387 if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer) 27 GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client) 28 : GraphicsLayer(client) 29 , m_node(new TextureMapperNode()) 30 , m_changeMask(0) 31 { 32 } 33 34 void GraphicsLayerTextureMapper::notifyChange(TextureMapperNode::ChangeMask changeMask) 35 { 36 m_changeMask |= changeMask; 37 if (!client()) 38 return; 39 client()->notifySyncRequired(this); 40 } 41 42 void GraphicsLayerTextureMapper::didSynchronize() 43 { 44 m_syncQueued = false; 45 m_changeMask = 0; 46 m_pendingContent.needsDisplay = false; 47 m_pendingContent.needsDisplayRect = IntRect(); 48 } 49 50 void GraphicsLayerTextureMapper::setName(const String& name) 51 { 52 GraphicsLayer::setName(name); 53 } 54 55 GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper() 56 { 57 } 58 59 /* \reimp (GraphicsLayer.h): The current size might change, thus we need to update the whole display. 60 */ 61 void GraphicsLayerTextureMapper::setNeedsDisplay() 62 { 63 m_pendingContent.needsDisplay = true; 64 notifyChange(TextureMapperNode::DisplayChange); 65 } 66 67 /* \reimp (GraphicsLayer.h) 68 */ 69 void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect) 70 { 71 if (m_pendingContent.needsDisplay) 72 return; 73 m_pendingContent.needsDisplayRect.unite(IntRect(rect)); 74 notifyChange(TextureMapperNode::DisplayChange); 75 } 76 77 /* \reimp (GraphicsLayer.h) 78 */ 79 void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer) 80 { 81 notifyChange(TextureMapperNode::ParentChange); 82 GraphicsLayer::setParent(layer); 83 } 84 85 /* \reimp (GraphicsLayer.h) 86 */ 87 bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children) 88 { 89 notifyChange(TextureMapperNode::ChildrenChange); 90 return GraphicsLayer::setChildren(children); 91 } 92 93 /* \reimp (GraphicsLayer.h) 94 */ 95 void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer) 96 { 97 notifyChange(TextureMapperNode::ChildrenChange); 98 GraphicsLayer::addChild(layer); 99 } 100 101 /* \reimp (GraphicsLayer.h) 102 */ 103 void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index) 104 { 105 GraphicsLayer::addChildAtIndex(layer, index); 106 notifyChange(TextureMapperNode::ChildrenChange); 107 } 108 109 /* \reimp (GraphicsLayer.h) 110 */ 111 void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling) 112 { 113 GraphicsLayer::addChildAbove(layer, sibling); 114 notifyChange(TextureMapperNode::ChildrenChange); 115 } 116 117 /* \reimp (GraphicsLayer.h) 118 */ 119 void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling) 120 { 121 122 GraphicsLayer::addChildBelow(layer, sibling); 123 notifyChange(TextureMapperNode::ChildrenChange); 124 } 125 126 /* \reimp (GraphicsLayer.h) 127 */ 128 bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild) 129 { 130 if (GraphicsLayer::replaceChild(oldChild, newChild)) { 131 notifyChange(TextureMapperNode::ChildrenChange); 388 132 return true; 389 const int size = m_children.size();390 for (int i = 0; i < size; ++i) {391 if (TextureMapperNode* child = m_children[i]) {392 if (child->hasSurfaceDescendants())393 return true;394 }395 133 } 396 134 return false; 397 398 }399 400 void TextureMapperNode::paint(TextureMapper* textureMapper, const TextureMapperContentLayer::PaintOptions& options)401 {402 ASSERT(m_layerType == RootLayer);403 if (m_size.isEmpty())404 return;405 406 #if 0407 WTF::StopWatch stopWatch;408 ("[TextureMapper] RootPaint!!\n");409 #endif410 411 if (textureMapper->type() != m_lastTextureMapperType)412 gTextureMapperCache.m_data.clear();413 414 m_lastTextureMapper = textureMapper;415 TexmapPaintOptions opt;416 opt.opacity = 1;417 opt.rootLayer = this;418 opt.scissorRect = options.targetRect;419 opt.visibleRect = options.visibleRect;420 opt.textureMapper = textureMapper;421 opt.surface = 0;422 paintRecursive(opt);423 424 if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) {425 textureMapper->bindSurface(0);426 textureMapper->paintToTarget(*m_surface.get(), options.viewportSize, options.transform, options.opacity * m_state.opacity, options.targetRect);427 }428 gTextureMapperCache.purge();429 }430 431 int TextureMapperNode::countDescendantsWithContent() const432 {433 if (!m_state.visible || m_state.opacity < 0.001)434 return 0;435 int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0;436 437 const int size = m_children.size();438 for (int i = 0; i < size; ++i) {439 if (TextureMapperNode* child = m_children[i])440 descendantsWithContent += child->countDescendantsWithContent();441 }442 443 return descendantsWithContent;444 }445 446 inline TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer)447 {448 return layer ? static_cast<GraphicsLayerTextureMapper*>(layer)->m_node.get() : 0;449 }450 451 void TextureMapperNode::computeLayerType()452 {453 // calculate layer type. A layer can be one of the following:454 // RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport.455 // only one layer is the root layer.456 // ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children.457 // A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip.458 // ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity.459 // A clip layer is a layer that masks to bounds, doesn't preserve 3D, has children, and has a transparency/mask or a non-rectangular transform.460 // TransparencyLayer: creates a new framebuffer idetical in size to the current framebuffer. Then draws the fb's texture to the current framebuffer with identity transform.461 // Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds.462 // DefaultLayer: draws itself and its children directly to the current framebuffer.463 // any layer that doesn't conform to the other rules is a DefaultLayer.464 465 const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType);466 const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0);467 const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer;468 const bool hasReplica = m_state.replicaLayer;469 m_layerType = DefaultLayer;470 471 // Layer has no parent, it must be a root layer.472 if (!m_parent && !m_effectTarget) {473 m_layerType = RootLayer;474 return;475 }476 477 // A layer with no contents is always a default layer.478 if (!m_state.descendantsWithContent)479 return;480 481 // A layer with content-descendants and a mask is always a clip layer.482 if (hasDescendantsWithContent && m_state.maskLayer) {483 m_layerType = ClipLayer;484 return;485 }486 487 // A masks-to bounds layer can be a clip or a scissor layer. It's a scissor layer only if it has a trivial clip (identity or translation), or if it has transparency.488 // That's because a ClipLayer would create an intermediate drawing surface (FB) - we want to limit it to when it's actually necessary, i.e. transparency or non-trivial clip.489 if (m_state.masksToBounds && hasDescendantsWithContent) {490 if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D)491 m_layerType = ClipLayer;492 else493 m_layerType = ScissorLayer;494 return;495 }496 497 // We use a transparency layer when we have two of the following 3: replica, transparency, descendants with contents.498 if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1))499 m_layerType = TransparencyLayer;500 }501 void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper)502 {503 if (textureMapper->type() == m_lastTextureMapperType)504 return;505 m_surface = textureMapper->createTexture();506 m_replicaSurface = textureMapper->createTexture();507 m_texture = textureMapper->createTexture();508 gTextureMapperCache.mark(m_texture.get());509 m_lastTextureMapperType = textureMapper->type();510 }511 512 TextureMapperNode::TextureMapperNode(GraphicsLayerTextureMapper* newLayer)513 : m_layer(newLayer)514 , m_lastTextureMapperType(0)515 , m_lastTextureMapper(0)516 , m_layerType(DefaultLayer)517 , m_surface(0)518 , m_parent(0)519 , m_effectTarget(0)520 , m_changeMask(NoChanges)521 , m_platformClient(0)522 {523 524 }525 526 TextureMapperNode* TextureMapperNode::rootLayer()527 {528 if (m_effectTarget)529 return m_effectTarget->rootLayer();530 if (m_parent)531 return m_parent->rootLayer();532 return this;533 }534 535 void TextureMapperNode::invalidateTransform()536 {537 m_transforms.dirty = true;538 if (m_layerType != ClipLayer)539 m_state.dirty = true;540 if (m_state.replicaLayer)541 m_state.replicaLayer->invalidateTransform();542 const int size = m_children.size();543 for (int i = 0; i < size; ++i) {544 if (TextureMapperNode* layer = m_children[i])545 layer->invalidateTransform();546 }547 }548 549 void TextureMapperNode::computeLocalTransform()550 {551 if (!m_transforms.localDirty)552 return;553 const float originX = m_state.anchorPoint.x() * m_size.width();554 const float originY = m_state.anchorPoint.y() * m_size.height();555 m_transforms.local =556 TransformationMatrix()557 .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())558 .multLeft(m_state.transform)559 .translate3d(-originX, -originY, -m_state.anchorPoint.z());560 m_transforms.localDirty = false;561 }562 563 void TextureMapperNode::flattenTo2DSpaceIfNecessary()564 {565 if (m_state.preserves3D)566 return;567 m_transforms.forDescendants.setM13(0);568 m_transforms.forDescendants.setM23(0);569 m_transforms.forDescendants.setM31(0);570 m_transforms.forDescendants.setM32(0);571 m_transforms.forDescendants.setM33(1);572 m_transforms.forDescendants.setM34(0);573 m_transforms.forDescendants.setM43(0);574 }575 576 IntSize TextureMapperNode::nearestSurfaceSize() const577 {578 if (m_layerType == ClipLayer || m_layerType == RootLayer)579 return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size;580 return m_parent->nearestSurfaceSize();581 }582 583 void TextureMapperNode::computeReplicaTransform()584 {585 if (!m_state.replicaLayer)586 return;587 588 m_nearestSurfaceSize = nearestSurfaceSize();589 590 if (m_layerType != TransparencyLayer) {591 m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local);592 return;593 }594 595 const float originX = m_transforms.target.m41();596 const float originY = m_transforms.target.m42();597 m_transforms.replica =598 TransformationMatrix()599 .translate(originX, originY)600 .multLeft(m_state.replicaLayer->m_transforms.local)601 .translate(-originX, -originY);602 }603 604 void TextureMapperNode::computeTransformations()605 {606 if (!m_transforms.dirty)607 return;608 609 m_transforms.dirty = false;610 if ((m_size.isEmpty() && m_state.masksToBounds))611 return;612 613 TextureMapperNode* parent = m_parent;614 computeLocalTransform();615 616 m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local);617 m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target);618 619 if (m_effectTarget)620 return;621 622 m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect()));623 if (m_state.replicaLayer)624 m_state.replicaLayer->computeTransformations();625 626 flattenTo2DSpaceIfNecessary();627 628 if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) {629 m_state.visible = false;630 return;631 }632 m_state.visible = true;633 634 if (parent && parent->m_state.preserves3D)635 m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z();636 637 if (!m_children.size())638 return;639 640 if (m_state.childrenTransform.isIdentity())641 return;642 643 const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2);644 if (m_transforms.perspectiveDirty)645 m_transforms.perspective = TransformationMatrix()646 .translate(centerPoint.x(), centerPoint.y())647 .multLeft(m_state.childrenTransform)648 .translate(-centerPoint.x(), -centerPoint.y());649 m_transforms.perspectiveDirty = false;650 m_transforms.forDescendants.multLeft(m_transforms.perspective);651 }652 653 void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect)654 {655 if (m_size.isEmpty() || !m_layer) {656 m_texture->destroy();657 return;658 }659 660 if (m_currentContent.contentType == DirectImageContentType) {661 if (m_currentContent.image)662 m_texture->setContentsToImage(m_currentContent.image.get());663 return;664 }665 666 if (m_currentContent.contentType == MediaContentType) {667 if (!m_currentContent.media)668 return;669 m_texture->reset(m_size, true);670 PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia();671 GraphicsContext context(platformContext);672 m_currentContent.media->paint(&context);673 m_texture->endPaint();674 return;675 }676 677 const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid();678 if ((m_currentContent.contentType != HTMLContentType)679 || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset))680 return;681 682 IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height());683 if (!needsReset && !m_currentContent.needsDisplay)684 dirtyRect.intersect(m_currentContent.needsDisplayRect);685 if (needsReset)686 m_texture->reset(m_size, m_state.contentsOpaque);687 m_pendingContent.needsDisplayRect = IntRect();688 689 {690 GraphicsContext context(m_texture->beginPaint(dirtyRect));691 if (textureMapper) {692 context.setImageInterpolationQuality(textureMapper->imageInterpolationQuality());693 context.setTextDrawingMode(textureMapper->textDrawingMode());694 }695 m_layer->paintGraphicsLayerContents(context, dirtyRect);696 }697 m_texture->endPaint();698 m_currentContent.needsDisplay = false;699 700 }701 702 void TextureMapperNode::paintSelf(const TexmapPaintOptions& options)703 {704 if (!m_layer || m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType))705 return;706 707 RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0;708 RefPtr<BitmapTexture> replicaMaskTexture = 0;709 if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer)710 replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture;711 712 const float opacity = options.isSurface ? 1 : options.opacity;713 714 uploadTextureFromContent(options.textureMapper, options.visibleRect);715 if (m_state.replicaLayer && !options.isSurface)716 options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica,717 opacity * m_state.replicaLayer->m_state.opacity,718 replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());719 720 const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect();721 const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target;722 options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get());723 }724 725 void TextureMapperNode::paintRecursive(TexmapPaintOptions options)726 {727 bool isDirty = m_state.dirty;728 m_state.dirty = false;729 730 if ((m_size.isEmpty() && (m_state.masksToBounds731 || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01)732 return;733 734 initializeTextureMapper(options.textureMapper);735 computeReplicaTransform();736 737 if (m_state.maskLayer) {738 m_state.maskLayer->initializeTextureMapper(options.textureMapper);739 m_state.maskLayer->m_state.dirty = false;740 }741 742 if (m_state.replicaLayer) {743 m_state.replicaLayer->initializeTextureMapper(options.textureMapper);744 m_state.replicaLayer->m_state.dirty = false;745 if (m_state.replicaLayer->m_state.maskLayer) {746 m_state.replicaLayer->m_state.maskLayer->initializeTextureMapper(options.textureMapper);747 m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false;748 }749 }750 751 TextureMapperNode* replica = m_state.replicaLayer;752 const bool isSurface = (m_layerType == ClipLayer753 || m_layerType == TransparencyLayer754 || (m_layerType == RootLayer755 && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants)756 ));757 if (isSurface)758 uploadTextureFromContent(options.textureMapper, options.visibleRect);759 const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect;760 761 options.opacity *= m_state.opacity;762 763 TexmapPaintOptions optionsForDescendants(options);764 optionsForDescendants.opacity = isSurface ? 1 : options.opacity;765 options.isSurface = isSurface;766 767 if (m_layerType == ClipLayer) {768 optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect);769 optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height());770 }771 772 if (m_layerType == ScissorLayer)773 optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect);774 options.textureMapper->setClip(optionsForDescendants.scissorRect);775 776 TextureMapperCacheLock(m_texture.get());777 TextureMapperCacheLock(m_surface.get());778 TextureMapperCacheLock(m_replicaSurface.get());779 780 gTextureMapperCache.purge();781 782 if (isSurface) {783 ASSERT(m_surface);784 if (!m_surface->isValid())785 isDirty = true;786 if (m_state.tiled) {787 m_surface->reset(options.visibleRect.size());788 m_surface->setOffset(options.visibleRect.location());789 } else if (isDirty)790 m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size);791 gTextureMapperCache.mark(m_surface.get());792 options.textureMapper->bindSurface(m_surface.get());793 794 optionsForDescendants.surface = m_surface.get();795 } else if (m_surface)796 m_surface->destroy();797 798 RefPtr<BitmapTexture> maskTexture;799 RefPtr<BitmapTexture> replicaMaskTexture;800 if (TextureMapperNode* mask = m_state.maskLayer) {801 mask->uploadTextureFromContent(options.textureMapper, options.visibleRect);802 maskTexture = mask->m_texture;803 }804 805 if (replica && replica->m_state.maskLayer) {806 replica->m_state.maskLayer->uploadTextureFromContent(options.textureMapper, options.visibleRect);807 replicaMaskTexture = replica->m_state.maskLayer->m_texture;808 }809 810 int childrenSize = m_children.size();811 if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid()) {812 bool didPaintSelf = false;813 if (!m_state.preserves3D || m_children.isEmpty()) {814 paintSelf(options);815 didPaintSelf = true;816 }817 818 if (m_children.isEmpty() && !isSurface)819 return;820 821 if (m_layerType == ScissorLayer)822 optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height())));823 824 for (int i = 0; i < childrenSize; ++i) {825 TextureMapperNode* layer = m_children[i];826 if (!layer)827 continue;828 829 if (!didPaintSelf && layer->m_transforms.centerZ >= 0) {830 paintSelf(options);831 didPaintSelf = true;832 }833 layer->paintRecursive(optionsForDescendants);834 if (isSurface) {835 ASSERT(m_surface);836 gTextureMapperCache.mark(m_surface.get());837 options.textureMapper->bindSurface(m_surface.get());838 }839 }840 if (!didPaintSelf) {841 paintSelf(options);842 didPaintSelf = true;843 }844 }845 846 if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer)847 return;848 849 ASSERT(m_surface);850 BitmapTexture& texture = *m_surface.get();851 if (replica) {852 ASSERT(m_replicaSurface);853 m_replicaSurface->reset(options.surface->size());854 m_replicaSurface->setOffset(options.surface->offset());855 gTextureMapperCache.mark(m_replicaSurface.get());856 options.textureMapper->bindSurface(m_replicaSurface.get());857 options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());858 options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get());859 options.textureMapper->bindSurface(options.surface);860 gTextureMapperCache.mark(options.surface);861 options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0);862 return;863 }864 865 options.textureMapper->bindSurface(options.surface);866 options.textureMapper->drawTexture(texture,867 m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) :868 targetRect(),869 m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target,870 options.opacity, maskTexture.get());871 gTextureMapperCache.mark(&texture);872 }873 874 void TextureMapperNode::cleanupTextureMapper()875 {876 if (m_texture)877 m_texture->destroy();878 if (m_surface)879 m_surface->destroy();880 if (m_replicaSurface)881 m_replicaSurface->destroy();882 for (int i = 0; i < m_children.size(); ++i) {883 if (m_children[i])884 m_children[i]->cleanupTextureMapper();885 }886 if (m_lastTextureMapper)887 m_lastTextureMapper->cleanup();888 }889 890 TextureMapperNode::~TextureMapperNode()891 {892 setNeedsDisplay();893 {894 const int childrenSize = m_children.size();895 for (int i = childrenSize-1; i >= 0; --i) {896 ASSERT(m_children[i]->m_parent == this);897 m_children[i]->m_parent = 0;898 }899 }900 if (m_parent)901 m_parent->m_children.remove(m_parent->m_children.find(this));902 }903 904 void TextureMapperNode::notifyChange(ChangeMask changeMask)905 {906 m_changeMask |= changeMask;907 if (!m_layer->client())908 return;909 m_layer->client()->notifySyncRequired(m_layer);910 }911 912 void TextureMapperNode::performPostSyncOperations()913 {914 const LayerType prevLayerType = m_layerType;915 computeLayerType();916 if (prevLayerType != m_layerType)917 m_state.dirty = true;918 if (m_transforms.dirty)919 setNeedsDisplay();920 921 computeTransformations();922 if (m_state.maskLayer && !m_state.dirty)923 m_state.dirty = m_state.maskLayer->m_state.dirty;924 if (m_state.replicaLayer && !m_state.dirty)925 m_state.dirty = m_state.replicaLayer->m_state.dirty;926 927 const int size = m_children.size();928 929 for (int i = size - 1; i >= 0; --i) {930 TextureMapperNode* layer = m_children[i];931 932 layer->performPostSyncOperations();933 if (!m_state.dirty)934 m_state.dirty = layer->m_state.dirty;935 }936 m_state.hasSurfaceDescendants = hasSurfaceDescendants();937 if (m_state.dirty)938 m_state.descendantsWithContent = countDescendantsWithContent();939 940 if (m_state.preserves3D)941 sortByZOrder(m_children, 0, size);942 if (m_state.dirty)943 setNeedsDisplay();944 }945 946 void TextureMapperNode::syncCompositingState(bool recurse)947 {948 bool needsToInvalidateTransform = false;949 950 if (!m_layer)951 return;952 953 if (m_changeMask == NoChanges)954 goto afterCurrentLayerSync;955 956 setNeedsDisplay();957 if (m_parent)958 m_parent->m_state.dirty = true;959 960 if (m_currentContent.contentType == HTMLContentType && (m_changeMask & ParentChange)) {961 // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't962 // try to snatch that ownership.963 964 if (!m_layer->parent())965 m_parent = 0;966 else967 m_parent = toTextureMapperNode(m_layer->parent());968 969 if (!m_layer->parent() && m_parent) {970 size_t index = m_parent->m_children.find(this);971 m_parent->m_children.remove(index);972 }973 974 }975 976 if (m_changeMask & ChildrenChange) {977 m_children.clear();978 for (size_t i = 0; i < m_layer->children().size(); ++i) {979 if (TextureMapperNode* child = toTextureMapperNode(m_layer->children()[i])) {980 if (!child)981 continue;982 m_children.append(child);983 child->m_parent = this;984 }985 }986 m_state.dirty = true;987 }988 989 if (m_changeMask & (SizeChange | ContentsRectChange)) {990 IntSize wantedSize = IntSize(m_layer->size().width(), m_layer->size().height());991 if (wantedSize.isEmpty() && m_pendingContent.contentType == HTMLContentType)992 wantedSize = IntSize(m_layer->contentsRect().width(), m_layer->contentsRect().height());993 994 if (wantedSize != m_size) {995 m_size = IntSize(wantedSize.width(), wantedSize.height());996 if (m_platformClient)997 m_platformClient->setSizeChanged(m_size);998 const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000;999 if (m_state.tiled != needsTiling)1000 m_state.tiled = needsTiling;1001 m_state.dirty = true;1002 }1003 }1004 1005 if (m_changeMask & MaskLayerChange) {1006 if (TextureMapperNode* layer = toTextureMapperNode(m_layer->maskLayer()))1007 layer->m_effectTarget = this;1008 }1009 1010 if (m_changeMask & ReplicaLayerChange) {1011 if (TextureMapperNode* layer = toTextureMapperNode(m_layer->replicaLayer()))1012 layer->m_effectTarget = this;1013 }1014 1015 if (m_changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange))1016 m_transforms.localDirty = true;1017 1018 if (m_changeMask & (ChildrenTransformChange | SizeChange))1019 m_transforms.perspectiveDirty = true;1020 1021 if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange)) {1022 // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms,1023 // all these elements affect the transforms of all the descendants.1024 needsToInvalidateTransform = true;1025 }1026 1027 if (m_changeMask & DisplayChange)1028 m_state.dirty = true;1029 1030 m_state.maskLayer = toTextureMapperNode(m_layer->maskLayer());1031 m_state.replicaLayer = toTextureMapperNode(m_layer->replicaLayer());1032 m_state.pos = m_layer->position();1033 m_state.anchorPoint = m_layer->anchorPoint();1034 m_state.size = m_layer->size();1035 m_state.transform = m_layer->transform();1036 m_state.contentsRect = m_layer->contentsRect();1037 m_state.opacity = m_layer->opacity();1038 m_state.contentsRect = m_layer->contentsRect();1039 m_state.preserves3D = m_layer->preserves3D();1040 m_state.masksToBounds = m_layer->masksToBounds();1041 m_state.drawsContent = m_layer->drawsContent();1042 m_state.contentsOpaque = m_layer->contentsOpaque();1043 m_state.backfaceVisibility = m_layer->backfaceVisibility();1044 m_state.childrenTransform = m_layer->childrenTransform();1045 m_currentContent.contentType = m_pendingContent.contentType;1046 m_currentContent.image = m_pendingContent.image;1047 m_currentContent.media = m_pendingContent.media;1048 m_currentContent.backgroundColor = m_pendingContent.backgroundColor;1049 m_currentContent.needsDisplay = m_currentContent.needsDisplay || m_pendingContent.needsDisplay;1050 m_currentContent.needsDisplayRect.unite(m_pendingContent.needsDisplayRect);1051 m_pendingContent.needsDisplay = false;1052 m_pendingContent.needsDisplayRect = IntRect();1053 m_changeMask = NoChanges;1054 afterCurrentLayerSync:1055 if (needsToInvalidateTransform)1056 invalidateTransform();1057 1058 if (m_state.maskLayer) {1059 m_state.maskLayer->syncCompositingState(false);1060 if (m_state.maskLayer->m_size.isEmpty())1061 m_state.maskLayer->m_size = m_size;1062 }1063 1064 if (m_state.replicaLayer)1065 m_state.replicaLayer->syncCompositingState(false);1066 1067 #if 01068 if (m_state.dirty && m_texture && m_texture->allowOfflineTextureUpload())1069 uploadTextureFromContent(0);1070 #endif1071 1072 if (!recurse)1073 return;1074 1075 const int childrenSize = m_children.size();1076 for (int i = childrenSize-1; i >= 0; --i)1077 m_children[i]->syncCompositingState(true);1078 }1079 1080 GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)1081 : GraphicsLayer(client)1082 , m_node(new TextureMapperNode(this))1083 {1084 }1085 1086 void GraphicsLayerTextureMapper::setName(const String& name)1087 {1088 m_node->m_name = name;1089 }1090 1091 GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()1092 {1093 }1094 1095 /* \reimp (GraphicsLayer.h): The current size might change, thus we need to update the whole display.1096 */1097 void GraphicsLayerTextureMapper::setNeedsDisplay()1098 {1099 m_node->m_pendingContent.needsDisplay = true;1100 m_node->notifyChange(TextureMapperNode::DisplayChange);1101 }1102 1103 /* \reimp (GraphicsLayer.h)1104 */1105 void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)1106 {1107 if (m_node->m_pendingContent.needsDisplay)1108 return;1109 m_node->m_pendingContent.needsDisplayRect.unite(IntRect(rect));1110 m_node->notifyChange(TextureMapperNode::DisplayChange);1111 }1112 1113 /* \reimp (GraphicsLayer.h)1114 */1115 void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer)1116 {1117 m_node->notifyChange(TextureMapperNode::ParentChange);1118 GraphicsLayer::setParent(layer);1119 }1120 1121 /* \reimp (GraphicsLayer.h)1122 */1123 bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children)1124 {1125 m_node->notifyChange(TextureMapperNode::ChildrenChange);1126 return GraphicsLayer::setChildren(children);1127 }1128 1129 /* \reimp (GraphicsLayer.h)1130 */1131 void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)1132 {1133 m_node->notifyChange(TextureMapperNode::ChildrenChange);1134 GraphicsLayer::addChild(layer);1135 }1136 1137 /* \reimp (GraphicsLayer.h)1138 */1139 void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index)1140 {1141 GraphicsLayer::addChildAtIndex(layer, index);1142 m_node->notifyChange(TextureMapperNode::ChildrenChange);1143 }1144 1145 /* \reimp (GraphicsLayer.h)1146 */1147 void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)1148 {1149 GraphicsLayer::addChildAbove(layer, sibling);1150 m_node->notifyChange(TextureMapperNode::ChildrenChange);1151 }1152 1153 /* \reimp (GraphicsLayer.h)1154 */1155 void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling)1156 {1157 1158 GraphicsLayer::addChildBelow(layer, sibling);1159 m_node->notifyChange(TextureMapperNode::ChildrenChange);1160 }1161 1162 /* \reimp (GraphicsLayer.h)1163 */1164 bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)1165 {1166 if (GraphicsLayer::replaceChild(oldChild, newChild)) {1167 m_node->notifyChange(TextureMapperNode::ChildrenChange);1168 return true;1169 }1170 1171 return false;1172 135 } 1173 136 … … 1178 141 if (!parent()) 1179 142 return; 1180 m_node->notifyChange(TextureMapperNode::ParentChange);143 notifyChange(TextureMapperNode::ParentChange); 1181 144 GraphicsLayer::removeFromParent(); 1182 145 } … … 1189 152 return; 1190 153 GraphicsLayer::setMaskLayer(value); 1191 m_node->notifyChange(TextureMapperNode::MaskLayerChange);154 notifyChange(TextureMapperNode::MaskLayerChange); 1192 155 } 1193 156 … … 1200 163 return; 1201 164 GraphicsLayer::setReplicatedByLayer(value); 1202 m_node->notifyChange(TextureMapperNode::ReplicaLayerChange);165 notifyChange(TextureMapperNode::ReplicaLayerChange); 1203 166 } 1204 167 … … 1210 173 return; 1211 174 GraphicsLayer::setPosition(value); 1212 m_node->notifyChange(TextureMapperNode::PositionChange);175 notifyChange(TextureMapperNode::PositionChange); 1213 176 } 1214 177 … … 1220 183 return; 1221 184 GraphicsLayer::setAnchorPoint(value); 1222 m_node->notifyChange(TextureMapperNode::AnchorPointChange);185 notifyChange(TextureMapperNode::AnchorPointChange); 1223 186 } 1224 187 … … 1231 194 1232 195 GraphicsLayer::setSize(value); 1233 m_node->notifyChange(TextureMapperNode::SizeChange);196 notifyChange(TextureMapperNode::SizeChange); 1234 197 } 1235 198 … … 1242 205 1243 206 GraphicsLayer::setTransform(value); 1244 m_node->notifyChange(TextureMapperNode::TransformChange);207 notifyChange(TextureMapperNode::TransformChange); 1245 208 } 1246 209 … … 1252 215 return; 1253 216 GraphicsLayer::setChildrenTransform(value); 1254 m_node->notifyChange(TextureMapperNode::ChildrenTransformChange);217 notifyChange(TextureMapperNode::ChildrenTransformChange); 1255 218 } 1256 219 … … 1262 225 return; 1263 226 GraphicsLayer::setPreserves3D(value); 1264 m_node->notifyChange(TextureMapperNode::Preserves3DChange);227 notifyChange(TextureMapperNode::Preserves3DChange); 1265 228 } 1266 229 … … 1272 235 return; 1273 236 GraphicsLayer::setMasksToBounds(value); 1274 m_node->notifyChange(TextureMapperNode::MasksToBoundsChange);237 notifyChange(TextureMapperNode::MasksToBoundsChange); 1275 238 } 1276 239 … … 1281 244 if (value == drawsContent()) 1282 245 return; 1283 m_node->notifyChange(TextureMapperNode::DrawsContentChange);246 notifyChange(TextureMapperNode::DrawsContentChange); 1284 247 GraphicsLayer::setDrawsContent(value); 1285 248 } … … 1289 252 void GraphicsLayerTextureMapper::setBackgroundColor(const Color& value) 1290 253 { 1291 if (value == m_ node->m_pendingContent.backgroundColor)1292 return; 1293 m_ node->m_pendingContent.backgroundColor = value;254 if (value == m_pendingContent.backgroundColor) 255 return; 256 m_pendingContent.backgroundColor = value; 1294 257 GraphicsLayer::setBackgroundColor(value); 1295 m_node->notifyChange(TextureMapperNode::BackgroundColorChange);258 notifyChange(TextureMapperNode::BackgroundColorChange); 1296 259 } 1297 260 … … 1300 263 void GraphicsLayerTextureMapper::clearBackgroundColor() 1301 264 { 1302 if (!m_ node->m_pendingContent.backgroundColor.isValid())1303 return; 1304 m_ node->m_pendingContent.backgroundColor = Color();265 if (!m_pendingContent.backgroundColor.isValid()) 266 return; 267 m_pendingContent.backgroundColor = Color(); 1305 268 GraphicsLayer::clearBackgroundColor(); 1306 m_node->notifyChange(TextureMapperNode::BackgroundColorChange);269 notifyChange(TextureMapperNode::BackgroundColorChange); 1307 270 } 1308 271 … … 1313 276 if (value == contentsOpaque()) 1314 277 return; 1315 m_node->notifyChange(TextureMapperNode::ContentsOpaqueChange);278 notifyChange(TextureMapperNode::ContentsOpaqueChange); 1316 279 GraphicsLayer::setContentsOpaque(value); 1317 280 } … … 1324 287 return; 1325 288 GraphicsLayer::setBackfaceVisibility(value); 1326 m_node->notifyChange(TextureMapperNode::BackfaceVisibilityChange);289 notifyChange(TextureMapperNode::BackfaceVisibilityChange); 1327 290 } 1328 291 … … 1334 297 return; 1335 298 GraphicsLayer::setOpacity(value); 1336 m_node->notifyChange(TextureMapperNode::OpacityChange);299 notifyChange(TextureMapperNode::OpacityChange); 1337 300 } 1338 301 … … 1344 307 return; 1345 308 GraphicsLayer::setContentsRect(value); 1346 m_node->notifyChange(TextureMapperNode::ContentsRectChange);309 notifyChange(TextureMapperNode::ContentsRectChange); 1347 310 } 1348 311 … … 1351 314 void GraphicsLayerTextureMapper::setContentsToImage(Image* image) 1352 315 { 1353 m_node->notifyChange(TextureMapperNode::ContentChange);1354 m_ node->m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType;1355 m_ node->m_pendingContent.image = image;316 notifyChange(TextureMapperNode::ContentChange); 317 m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType; 318 m_pendingContent.image = image; 1356 319 GraphicsLayer::setContentsToImage(image); 1357 320 } … … 1361 324 void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color) 1362 325 { 1363 m_node->notifyChange(TextureMapperNode::ContentChange);1364 m_ node->m_pendingContent.contentType = TextureMapperNode::ColorContentType;1365 m_ node->m_pendingContent.backgroundColor = color;326 notifyChange(TextureMapperNode::ContentChange); 327 m_pendingContent.contentType = TextureMapperNode::ColorContentType; 328 m_pendingContent.backgroundColor = color; 1366 329 GraphicsLayer::setContentsBackgroundColor(color); 1367 330 } … … 1371 334 { 1372 335 GraphicsLayer::setContentsToMedia(media); 1373 m_node->notifyChange(TextureMapperNode::ContentChange);1374 m_ node->m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;336 notifyChange(TextureMapperNode::ContentChange); 337 m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType; 1375 338 if (media) 1376 m_ node->m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media);339 m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media); 1377 340 else 1378 m_ node->m_pendingContent.media = 0;341 m_pendingContent.media = 0; 1379 342 } 1380 343 … … 1385 348 if (contentsOrientation() == orientation) 1386 349 return; 1387 m_node->notifyChange(TextureMapperNode::ContentsOrientationChange);350 notifyChange(TextureMapperNode::ContentsOrientationChange); 1388 351 GraphicsLayer::setContentsOrientation(orientation); 1389 352 } … … 1393 356 void GraphicsLayerTextureMapper::syncCompositingStateForThisLayerOnly() 1394 357 { 1395 m_node->syncCompositingState(false); 1396 m_node->performPostSyncOperations(); 358 m_node->syncCompositingState(this, false); 1397 359 } 1398 360 … … 1401 363 void GraphicsLayerTextureMapper::syncCompositingState() 1402 364 { 1403 GraphicsLayer::syncCompositingState(); 1404 m_node->syncCompositingState(true); 1405 m_node->performPostSyncOperations(); 365 m_node->syncCompositingState(this, true); 1406 366 } 1407 367 -
trunk/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
r69374 r71538 25 25 #include "GraphicsLayerClient.h" 26 26 #include "Image.h" 27 #include "TextureMapperNode.h" 27 28 28 29 #if ENABLE(3D_CANVAS) 29 30 #include "GraphicsContext3D.h" 30 31 #endif 31 32 #define ENABLE_TEXMAP_ANIMATION 033 32 34 33 namespace WebCore { … … 86 85 virtual PlatformLayer* platformLayer() const; 87 86 88 virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, 89 const String& /*keyframesName*/, double /*timeOffset*/) { return false; } 87 virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; } 88 89 void notifyChange(TextureMapperNode::ChangeMask changeMask); 90 inline TextureMapperNode::ContentData& pendingContent() { return m_pendingContent; } 91 inline int changeMask() const { return m_changeMask; } 92 void didSynchronize(); 90 93 91 94 private: 92 95 OwnPtr<TextureMapperNode> m_node; 96 bool m_syncQueued; 97 int m_changeMask; 98 TextureMapperNode::ContentData m_pendingContent; 93 99 }; 100 101 inline static GraphicsLayerTextureMapper* toGraphicsLayerTextureMapper(GraphicsLayer* layer) 102 { 103 return static_cast<GraphicsLayerTextureMapper*>(layer); 104 } 94 105 95 106 } -
trunk/WebCore/platform/graphics/texmap/TextureMapper.h
r71213 r71538 58 58 } 59 59 60 virtual void pack() { } 61 virtual void unpack() { } 62 virtual bool isPacked() const { return false; } 63 60 64 virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect) = 0; 61 65 virtual void endPaint() = 0; … … 73 77 inline void setOffset(const IntPoint& o) { m_offset = o; } 74 78 inline IntPoint offset() const { return m_offset; } 79 80 protected: 81 75 82 private: 76 83 int m_lockCount; … … 82 89 // A "context" class used to encapsulate accelerated texture mapping functions: i.e. drawing a texture 83 90 // onto the screen or into another texture with a specified transform, opacity and mask. 84 class TextureMapper : public RefCounted<TextureMapper>{91 class TextureMapper { 85 92 friend class BitmapTexture; 86 93 87 94 public: 88 static Pass RefPtr<TextureMapper> create(GraphicsContext*);95 static PassOwnPtr<TextureMapper> create(GraphicsContext* graphicsContext = 0); 89 96 virtual ~TextureMapper() { } 90 97 … … 102 109 virtual bool allowSurfaceForRoot() const = 0; 103 110 virtual PassRefPtr<BitmapTexture> createTexture() = 0; 104 virtual const char* type() const = 0;105 virtual void cleanup() {}106 111 107 112 void setImageInterpolationQuality(InterpolationQuality quality) { m_interpolationQuality = quality; } -
trunk/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
r71213 r71538 37 37 virtual void setNeedsDisplayInRect(const IntRect& rect) = 0; 38 38 virtual void setSizeChanged(const IntSize&) = 0; 39 virtual TextureMapper* textureMapper() = 0; 39 40 }; 40 41 -
trunk/WebKit/qt/Api/qwebframe.cpp
r71217 r71538 310 310 return; 311 311 312 if (!textureMapper)313 textureMapper = TextureMapper::create(context);314 315 312 textureMapper->setGraphicsContext(context); 316 313 textureMapper->setImageInterpolationQuality(context->imageInterpolationQuality()); -
trunk/WebKit/qt/Api/qwebframe_p.h
r71213 r71538 114 114 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) 115 115 WebCore::TextureMapperContentLayer* rootGraphicsLayer; 116 RefPtr<WebCore::TextureMapper> textureMapper;116 OwnPtr<WebCore::TextureMapper> textureMapper; 117 117 #endif 118 118 bool zoomTextOnly; -
trunk/WebKit/qt/ChangeLog
r71499 r71538 1 2010-11-08 Noam Rosenthal <noam.rosenthal@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 [Texmap] [Qt] Texture mapper initial implementation 6 https://bugs.webkit.org/show_bug.cgi?id=47070 7 8 Reorganized the textureMapper to be a member of QWebFramePrivate, to help with making 9 TextureMapper thread-safe. 10 11 * Api/qwebframe.cpp: 12 (QWebFramePrivate::renderCompositedLayers): 13 * Api/qwebframe_p.h: 14 * WebCoreSupport/PageClientQt.cpp: 15 (WebCore::PlatformLayerProxyQt::setTextureMapper): 16 (WebCore::PlatformLayerProxyQt::textureMapper): 17 (WebCore::PlatformLayerProxyQWidget::PlatformLayerProxyQWidget): 18 (WebCore::PlatformLayerProxyQGraphicsObject::PlatformLayerProxyQGraphicsObject): 19 1 20 2010-11-07 Adam Barth <abarth@webkit.org> 2 21 -
trunk/WebKit/qt/WebCoreSupport/PageClientQt.cpp
r70819 r71538 22 22 23 23 #include "PageClientQt.h" 24 #include "TextureMapperQt.h" 24 25 #include "texmap/TextureMapperPlatformLayer.h" 25 26 #include <QGraphicsScene> 27 #include <QGraphicsView> 26 28 #if defined(Q_WS_X11) 27 29 #include <QX11Info> … … 29 31 30 32 #ifdef QT_OPENGL_LIB 33 #include "opengl/TextureMapperGL.h" 31 34 #include <QGLWidget> 32 35 #endif 36 33 37 namespace WebCore { 34 38 … … 46 50 } 47 51 52 void setTextureMapper(PassOwnPtr<TextureMapper> textureMapper) 53 { 54 m_frame->d->textureMapper = textureMapper; 55 } 56 48 57 virtual ~PlatformLayerProxyQt() 49 58 { … … 52 61 if (m_frame->d) 53 62 m_frame->d->rootGraphicsLayer = 0; 63 } 64 65 virtual TextureMapper* textureMapper() 66 { 67 return m_frame->d->textureMapper.get(); 54 68 } 55 69 … … 70 84 if (m_widget) 71 85 m_widget->installEventFilter(this); 86 87 if (textureMapper()) 88 return; 89 90 setTextureMapper(TextureMapperQt::create()); 72 91 } 73 92 … … 104 123 , m_graphicsItem(object) 105 124 { 125 if (textureMapper()) 126 return; 127 128 #ifdef QT_OPENGL_LIB 129 QGraphicsView* view = object->scene()->views()[0]; 130 if (view && view->viewport() && view->viewport()->inherits("QGLWidget")) { 131 setTextureMapper(TextureMapperGL::create()); 132 return; 133 } 134 #endif 135 setTextureMapper(TextureMapperQt::create()); 106 136 } 107 137
Note: See TracChangeset
for help on using the changeset viewer.