// An image can be directly compositing if it's the sole content of the layer, and has no box decorations
// that require painting. Direct compositing saves backing store.
bool CompositedLayerMapping::isDirectlyCompositedImage() const
{
RenderObject* renderObject = renderer();
if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground() || renderObject->hasClip())
return false;
RenderImage* imageRenderer = toRenderImage(renderObject);
if (ImageResource* cachedImage = imageRenderer->cachedImage()) {
if (!cachedImage->hasImage())
return false;
Image* image = cachedImage->imageForRenderer(imageRenderer);
return image->isBitmapImage();
}
return false;
}
void CompositedLayerMapping::contentChanged(ContentChangeType changeType)
{
if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
updateImageContents();
return;
}
if ((changeType == MaskImageChanged) && m_maskLayer) {
// The composited layer bounds relies on box->maskClipRect(), which changes
// when the mask image becomes available.
updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
}
if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && isAcceleratedCanvas(renderer())) {
m_graphicsLayer->setContentsNeedsDisplay();
return;
}
}
void CompositedLayerMapping::updateImageContents()
{
ASSERT(renderer()->isImage());
RenderImage* imageRenderer = toRenderImage(renderer());
ImageResource* cachedImage = imageRenderer->cachedImage();
if (!cachedImage)
return;
Image* image = cachedImage->imageForRenderer(imageRenderer);
if (!image)
return;
// We have to wait until the image is fully loaded before setting it on the layer.
if (!cachedImage->isLoaded())
return;
// This is a no-op if the layer doesn't have an inner layer for the image.
m_graphicsLayer->setContentsToImage(image);
bool isSimpleContainer = false;
updateDrawsContent(isSimpleContainer);
void GraphicsLayer::setContentsToImage(Image* image)
{
RefPtr<NativeImageSkia> nativeImage = image ? image->nativeImageForCurrentFrame() : 0;
if (nativeImage) {
if (!m_imageLayer) {
m_imageLayer = adoptPtr(Platform::current()->compositorSupport()->createImageLayer());
registerContentsLayer(m_imageLayer->layer());
}
m_imageLayer->setBitmap(nativeImage->bitmap());
m_imageLayer->layer()->setOpaque(image->currentFrameKnownToBeOpaque());
updateContentsRect();
} else {
if (m_imageLayer) {
unregisterContentsLayer(m_imageLayer->layer());
m_imageLayer.clear();
}
}
setContentsTo(m_imageLayer ? m_imageLayer->layer() : 0);
}
M39上反而不是这个行为,都会走NativeImageSkia::draw。当然,M39上SlimmingPaint和Ganesh(GPU Rasterization)仍然在持续重构中。