从之前的文章中我们知道,image是一种派生资源,它下载之后会有memory cache机制进行缓存,而image对应的缓存类为CacheImage。CacheImage有一个成员SharedBuffer存储的是图片元数据,也就是没解码前的数据(由loader传递而来)。还有一个Image对象(实际是个BitmapImage),该对象在GraphicsContext绘制时使用。看如下堆栈:
#4 WebCore::BitmapImage::frameDurationAtIndex (this=0x4daf1a78, index=0) at common/external/webkit/Source/WebCore/platform/graphics/BitmapImage.cpp:264
#5 WebCore::BitmapImage::startAnimation
#6 WebCore::BitmapImage::startAnimation
#7 WebCore::BitmapImage::draw ImageAndroid.cpp:180
#8 WebCore::Image::drawTiled
#9 WebCore::GraphicsContext::drawTiledImage
BitmapImage在绘制时会去找,这个图片是不是已在m_frames对象中被缓存,如果被缓存则直接使用,如果没有则创建缓存。那么缓存是怎么创建的呢?
#1 0x5ae11e2a in WebCore::ImageSource::createFrameAtIndex ImageSourceAndroid.cpp:389
#2 0x5ae01912 in WebCore::BitmapImage::cacheFrame
可见在ImageSource中被创建,注意android的实现在ImageSourceAndroid.cpp中。可见解码后的数据应该存在ImageSource中。实际上ImageSource有一个NativeImageSourcePtr对象,该对象中又有一个PrivateAndroidImageSoureRec对象存储着解码后的SkBitmap。其中解码过程如下:
#0 WebCore::ImageSource::setData ImageSourceAndroid.cpp:243
#1 WebCore::BitmapImage::dataChanged
#2 WebCore::Image::setData
#3 WebCore::CachedImage::data
#4 WebCore::CachedImage::data
#5 WebCore::CachedResourceRequest::didFinishLoading
这个setData的过程就是将前述的SharedBuffer元数据传递的过程,最终在ImageSource::setData(android实现在ImageSourceAndroid.cpp中)中调用Skia库相应的解码类来进行解码。
这个过程有一点乱,我们以一个类图来梳理一下:
另外更新一下图片作为背景时的绘制流程:
#0 WebCore::PlatformGraphicsContextSkia::drawBitmapRect (this=0xa93ff8c8, bitmap=..., src=0xa93fef60, dst=..., op=WebCore::CompositeSourceOver)
at external/webkit/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp:332
#1 0xaa6263de in WebCore::BitmapImage::draw (this=<optimized out>, gc=<optimized out>, dstRect=..., srcRect=..., compositeOp=WebCore::CompositeSourceOver)
at external/webkit/Source/WebCore/platform/graphics/android/ImageAndroid.cpp:212
#2 0xaa61fab0 in WebCore::Image::drawTiled (this=this@entry=0xa944f600, ctxt=ctxt@entry=0xa93ff8f0, destRect=..., srcPoint=..., scaledTileSize=...,
styleColorSpace=styleColorSpace@entry=WebCore::ColorSpaceDeviceRGB, op=op@entry=WebCore::CompositeSourceOver) at external/webkit/Source/WebCore/platform/graphics/Image.cpp:136
#3 0xaa61d9a2 in WebCore::GraphicsContext::drawTiledImage (this=this@entry=0xa93ff8f0, image=image@entry=0xa944f600, styleColorSpace=styleColorSpace@entry=WebCore::ColorSpaceDeviceRGB, rect=...,
srcPoint=..., tileSize=..., op=op@entry=WebCore::CompositeSourceOver, useLowQualityScale=false) at external/webkit/Source/WebCore/platform/graphics/GraphicsContext.cpp:515
#4 0xaa6c4810 in WebCore::RenderBoxModelObject::paintFillLayerExtended (this=<optimized out>, paintInfo=..., color=..., bgLayer=bgLayer@entry=0xa9466604, tx=tx@entry=0, ty=ty@entry=0, w=w@entry=960,
h=h@entry=576, box=box@entry=0x0, inlineBoxWidth=inlineBoxWidth@entry=0, inlineBoxHeight=inlineBoxHeight@entry=0, op=op@entry=WebCore::CompositeSourceOver, backgroundObject=backgroundObject@entry=
0xa9592328) at external/webkit/Source/WebCore/rendering/RenderBoxModelObject.cpp:766
#5 0xaa6bcef6 in WebCore::RenderBox::paintFillLayer (this=<optimized out>, paintInfo=..., c=..., fillLayer=fillLayer@entry=0xa9466604, tx=0, ty=0, width=960, height=576, op=WebCore::CompositeSourceOver,
backgroundObject=0xa9592328) at external/webkit/Source/WebCore/rendering/RenderBox.cpp:975
#6 0xaa6bcf5c in WebCore::RenderBox::paintFillLayers (this=this@entry=0xa95921cc, paintInfo=..., c=..., fillLayer=fillLayer@entry=0xa9466604, tx=0, ty=0, width=width@entry=960, height=576,
op=op@entry=WebCore::CompositeSourceOver, backgroundObject=backgroundObject@entry=0xa9592328) at external/webkit/Source/WebCore/rendering/RenderBox.cpp:970
#7 0xaa6bd020 in WebCore::RenderBox::paintRootBoxFillLayers (this=this@entry=0xa95921cc, paintInfo=...) at external/webkit/Source/WebCore/rendering/RenderBox.cpp:818
#8 0xaa6bd0f8 in WebCore::RenderBox::paintBoxDecorationsWithSize (this=0xa95921cc, paintInfo=..., tx=0, ty=0, width=960, height=height@entry=576)
at external/webkit/Source/WebCore/rendering/RenderBox.cpp:843
#9 0xaa6bd242 in WebCore::RenderBox::paintBoxDecorations (this=<optimized out>, paintInfo=..., tx=<optimized out>, ty=<optimized out>) at external/webkit/Source/WebCore/rendering/RenderBox.cpp:825
#10 0xaa6b3772 in WebCore::RenderBlock::paintObject (this=0xa95921cc, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2506
#11 0xaa6ab220 in WebCore::RenderBlock::paint (this=0xa95921cc, paintInfo=..., tx=0, ty=0) at external/webkit/Source/WebCore/rendering/RenderBlock.cpp:2312
#12 0xaa6d7a22 in WebCore::RenderLayer::paintLayer (this=0xa9592248, rootLayer=rootLayer@entry=0xa95920ec, p=p@entry=0xa93ff8f0, paintDirtyRect=..., paintBehavior=paintBehavior@entry=0,
paintingRoot=paintingRoot@entry=0x0, overlapTestRequests=overlapTestRequests@entry=0xa93ff7ec, paintFlags=paintFlags@entry=0) at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:2704
#13 0xaa6d7f02 in WebCore::RenderLayer::paintList (this=this@entry=0xa95920ec, list=0xa80e5ca0, rootLayer=rootLayer@entry=0xa95920ec, p=p@entry=0xa93ff8f0, paintDirtyRect=...,
paintBehavior=paintBehavior@entry=0, paintingRoot=paintingRoot@entry=0x0, overlapTestRequests=overlapTestRequests@entry=0xa93ff7ec, paintFlags=paintFlags@entry=0)
at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:2789
#14 0xaa6d7936 in WebCore::RenderLayer::paintLayer (this=this@entry=0xa95920ec, rootLayer=rootLayer@entry=0xa95920ec, p=p@entry=0xa93ff8f0, paintDirtyRect=..., paintBehavior=0,
paintingRoot=paintingRoot@entry=0x0, overlapTestRequests=overlapTestRequests@entry=0xa93ff7ec, paintFlags=paintFlags@entry=0) at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:2751
#15 0xaa6d7aec in WebCore::RenderLayer::paint (this=this@entry=0xa95920ec, p=p@entry=0xa93ff8f0, damageRect=..., paintBehavior=<optimized out>, paintingRoot=paintingRoot@entry=0x0)
at external/webkit/Source/WebCore/rendering/RenderLayer.cpp:2523
#16 0xaa5f6f98 in WebCore::FrameView::paintContents (this=0xa9439600, p=0xa93ff8f0, rect=...) at external/webkit/Source/WebCore/page/FrameView.cpp:2424
#17 0xab257112 in android::WebFrameView::draw (this=<optimized out>, gc=0xa93ff8f0, rect=...) at external/webkit/Source/WebKit/gaia/jni/WebFrameView.cpp:64
#18 0xab259bd2 in android::WebViewCore::paintContents (this=<optimized out>, gc=0xa93ff8f0, dirty=...) at external/webkit/Source/WebKit/gaia/jni/WebViewCore.cpp:682
#19 0xab253782 in WebCore::PicturePile::updatePicture (this=this@entry=0xa9442064, painter=painter@entry=0xa9442048, pc=...) at external/webkit/Source/WebKit/gaia/jni/PicturePile.cpp:201
#20 0xab2537e2 in WebCore::PicturePile::updatePicturesIfNeeded (this=this@entry=0xa9442064, painter=painter@entry=0xa9442048) at external/webkit/Source/WebKit/gaia/jni/PicturePile.cpp:162
#21 0xab25a3ea in android::WebViewCore::recordPicturePile (this=this@entry=0xa9442040) at external/webkit/Source/WebKit/gaia/jni/WebViewCore.cpp:653
#22 0xab25ee4e in android::WebViewCore::recordContent (this=0xa9442040, point=point@entry=0xa93ffa08) at external/webkit/Source/WebKit/gaia/jni/WebViewCore.cpp:853
#23 0xab25eea6 in android::RecordContent (nativeClass=<optimized out>, pt=...) at external/webkit/Source/WebKit/gaia/jni/WebViewCore.cpp:4562
#24 0xab32b238 in WebKit::WebViewCore::nativeRecordContent (this=this@entry=0xa9461520, nativeClass=<optimized out>, wh=...)
at external/webkit/Source/WebKit/gaia/frameworks/webkit/proxy/WebViewCoreNative.cpp:56
#25 0xab3142d0 in WebKit::WebViewCore::webkitDraw (this=0xa9461520) at external/webkit/Source/WebKit/gaia/frameworks/webkit/WebViewCore.cpp:1085