+2012-11-13 Huang Dongsung <luxtella@company100.net>
+
+ Coordinated Graphics: Directly composited animated GIFs only render the first image.
+ https://bugs.webkit.org/show_bug.cgi?id=102043
+
+ Reviewed by Noam Rosenthal.
+
+ CoordinatedGraphicsLayer::setContentsToImage() checks the pointer to the image,
+ not nativeImagePtr, so Coordinated Graphics currently draws only the first frame
+ of gif animations. This patch makes Coordinated Graphics draw gif animations.
+
+ In addition, this patch modifies the style of direct image compositing
+ code to match other parts of CoordinatedGraphicsLayer.
+
+ Test: ManualTests/animated-gif-on-compositing-layer.html
+
+ * WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp:
+ (WebCore::CoordinatedGraphicsLayer::didChangeImageBacking):
+ (WebCore):
+ (WebCore::CoordinatedGraphicsLayer::CoordinatedGraphicsLayer):
+ (WebCore::CoordinatedGraphicsLayer::setContentsNeedsDisplay):
+ (WebCore::CoordinatedGraphicsLayer::setContentsToImage):
+ (WebCore::CoordinatedGraphicsLayer::syncImageBacking):
+ (WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly):
+ (WebCore::CoordinatedGraphicsLayer::releaseImageBackingIfNeeded):
+ (WebCore::CoordinatedGraphicsLayer::purgeBackingStores):
+ (WebCore::CoordinatedGraphicsLayer::hasPendingVisibleChanges):
+ * WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.h:
+ (CoordinatedGraphicsLayer):
+
2012-11-12 Huang Dongsung <luxtella@company100.net>
[Qt] REGRESSION(134142): overscaled tiles in pixel test results and MiniBrowser
}
#endif
+void CoordinatedGraphicsLayer::didChangeImageBacking()
+{
+ m_shouldSyncImageBacking = true;
+ if (client())
+ client()->notifyFlushRequired(this);
+}
+
void CoordinatedGraphicsLayer::setShouldUpdateVisibleRect()
{
m_shouldUpdateVisibleRect = true;
, m_shouldSyncLayerState(true)
, m_shouldSyncChildren(true)
, m_shouldSyncFilters(true)
+ , m_shouldSyncImageBacking(true)
, m_shouldSyncAnimations(true)
, m_fixedToViewport(false)
, m_canvasNeedsDisplay(false)
, m_CoordinatedGraphicsLayerClient(0)
, m_contentsScale(1)
+ , m_compositedNativeImagePtr(0)
, m_canvasPlatformLayer(0)
, m_animationStartedTimer(this, &CoordinatedGraphicsLayer::animationStartedTimerFired)
{
void CoordinatedGraphicsLayer::setContentsNeedsDisplay()
{
- RefPtr<Image> image = m_image;
- setContentsToImage(0);
- setContentsToImage(image.get());
m_canvasNeedsDisplay = true;
if (client())
client()->notifyFlushRequired(this);
void CoordinatedGraphicsLayer::setContentsToImage(Image* image)
{
- if (image == m_image)
- return;
- int64_t newID = 0;
- if (m_CoordinatedGraphicsLayerClient) {
- // We adopt first, in case this is the same frame - that way we avoid destroying and recreating the image.
- newID = m_CoordinatedGraphicsLayerClient->adoptImageBackingStore(image);
- m_CoordinatedGraphicsLayerClient->releaseImageBackingStore(m_layerInfo.imageBackingStoreID);
- didChangeLayerState();
- if (m_layerInfo.imageBackingStoreID && newID == m_layerInfo.imageBackingStoreID)
+ if (image) {
+ // This code makes the assumption that pointer equality on a NativeImagePtr is a valid way to tell if the image is changed.
+ // This assumption is true in Qt, GTK and EFL.
+ NativeImagePtr newNativeImagePtr = image->nativeImageForCurrentFrame();
+ if (!newNativeImagePtr)
+ return;
+
+ if (newNativeImagePtr == m_compositedNativeImagePtr)
return;
+
+ m_compositedImage = image;
+ m_compositedNativeImagePtr = newNativeImagePtr;
} else {
- // If m_CoordinatedGraphicsLayerClient is not set yet there should be no backing store ID.
- ASSERT(!m_layerInfo.imageBackingStoreID);
- didChangeLayerState();
+ m_compositedImage = 0;
+ m_compositedNativeImagePtr = 0;
}
- m_layerInfo.imageBackingStoreID = newID;
- m_image = image;
GraphicsLayer::setContentsToImage(image);
+ didChangeImageBacking();
}
void CoordinatedGraphicsLayer::setMaskLayer(GraphicsLayer* layer)
return false;
return true;
-
- // TODO: don't directly composite images with more than one frame.
}
void CoordinatedGraphicsLayer::setReplicatedByLayer(GraphicsLayer* layer)
}
#endif
+void CoordinatedGraphicsLayer::syncImageBacking()
+{
+ if (!m_shouldSyncImageBacking)
+ return;
+ m_shouldSyncImageBacking = false;
+
+ releaseImageBackingIfNeeded();
+
+ if (m_compositedNativeImagePtr) {
+ ASSERT(!m_mainBackingStore);
+ ASSERT(m_compositedImage);
+
+ m_layerInfo.imageBackingStoreID = m_CoordinatedGraphicsLayerClient->adoptImageBackingStore(m_compositedImage.get());
+ }
+
+ // This method changes m_layerInfo.imageBackingStoreID.
+ didChangeLayerState();
+}
+
void CoordinatedGraphicsLayer::syncLayerState()
{
if (!m_shouldSyncLayerState)
m_canvasNeedsDisplay = false;
}
-void CoordinatedGraphicsLayer::ensureImageBackingStore()
-{
- if (!m_image)
- return;
- if (!m_layerInfo.imageBackingStoreID)
- m_layerInfo.imageBackingStoreID = m_CoordinatedGraphicsLayerClient->adoptImageBackingStore(m_image.get());
-}
-
void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly()
{
- // The remote image might have been released by purgeBackingStores.
- ensureImageBackingStore();
+ syncImageBacking();
syncLayerState();
syncAnimations();
computeTransformedVisibleRect();
syncCanvas();
}
+void CoordinatedGraphicsLayer::releaseImageBackingIfNeeded()
+{
+ if (!m_layerInfo.imageBackingStoreID)
+ return;
+
+ ASSERT(m_CoordinatedGraphicsLayerClient);
+ m_CoordinatedGraphicsLayerClient->releaseImageBackingStore(m_layerInfo.imageBackingStoreID);
+ m_layerInfo.imageBackingStoreID = 0;
+}
+
void CoordinatedGraphicsLayer::tiledBackingStorePaintBegin()
{
}
m_mainBackingStore.clear();
m_previousBackingStore.clear();
- if (m_layerInfo.imageBackingStoreID) {
- m_CoordinatedGraphicsLayerClient->releaseImageBackingStore(m_layerInfo.imageBackingStoreID);
- m_layerInfo.imageBackingStoreID = 0;
- }
+ releaseImageBackingIfNeeded();
didChangeLayerState();
didChangeChildren();
return true;
}
- if (!m_shouldSyncLayerState && !m_shouldSyncChildren && !m_shouldSyncFilters && !m_shouldSyncAnimations && !m_canvasNeedsDisplay)
+ if (!m_shouldSyncLayerState && !m_shouldSyncChildren && !m_shouldSyncFilters && !m_shouldSyncImageBacking && !m_shouldSyncAnimations && !m_canvasNeedsDisplay)
return false;
return selfOrAncestorHaveNonAffineTransforms() || !tiledBackingStoreVisibleRect().isEmpty();
#if ENABLE(CSS_FILTERS)
void didChangeFilters();
#endif
+ void didChangeImageBacking();
void syncLayerState();
void syncAnimations();
#if ENABLE(CSS_FILTERS)
void syncFilters();
#endif
+ void syncImageBacking();
void syncCanvas();
void ensureImageBackingStore();
void computeTransformedVisibleRect();
void updateContentBuffers();
void createBackingStore();
+ void releaseImageBackingIfNeeded();
bool selfOrAncestorHaveNonAffineTransforms();
bool shouldUseTiledBackingStore();
WebKit::WebLayerID m_id;
WebKit::WebLayerInfo m_layerInfo;
- RefPtr<Image> m_image;
GraphicsLayer* m_maskTarget;
FloatRect m_needsDisplayRect;
GraphicsLayerTransform m_layerTransform;
bool m_shouldSyncLayerState: 1;
bool m_shouldSyncChildren: 1;
bool m_shouldSyncFilters: 1;
+ bool m_shouldSyncImageBacking: 1;
bool m_shouldSyncAnimations: 1;
bool m_fixedToViewport : 1;
bool m_canvasNeedsDisplay : 1;
OwnPtr<TiledBackingStore> m_mainBackingStore;
OwnPtr<TiledBackingStore> m_previousBackingStore;
float m_contentsScale;
+
+ RefPtr<Image> m_compositedImage;
+ NativeImagePtr m_compositedNativeImagePtr;
+
PlatformLayer* m_canvasPlatformLayer;
Timer<CoordinatedGraphicsLayer> m_animationStartedTimer;
GraphicsLayerAnimations m_animations;