diff options
author | junov@chromium.org <junov@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-04-11 17:52:05 +0000 |
---|---|---|
committer | junov@chromium.org <junov@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-04-11 17:52:05 +0000 |
commit | 45c3db827d5bcb7c08bf49eff035be667332ec05 (patch) | |
tree | dd69e7516415b3501e549084f9f67cbf606313b3 /src/image | |
parent | 746cd0fc9a83766db28b937d40ecea2c0aea1483 (diff) |
Fixed bug in SkSurface_Gpu to make the surface receive the new copy when copy
on write happens.
Review URL: https://codereview.chromium.org/13195002
git-svn-id: http://skia.googlecode.com/svn/trunk@8622 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/image')
-rw-r--r-- | src/image/SkImagePriv.h | 5 | ||||
-rw-r--r-- | src/image/SkImage_Picture.cpp | 6 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 33 |
3 files changed, 23 insertions, 21 deletions
diff --git a/src/image/SkImagePriv.h b/src/image/SkImagePriv.h index 3210cae031..fc14f67c58 100644 --- a/src/image/SkImagePriv.h +++ b/src/image/SkImagePriv.h @@ -55,10 +55,13 @@ static inline size_t SkImageMinRowBytes(const SkImage::Info& info) { // in which case the surface may need to perform a copy-on-write. extern SkPixelRef* SkBitmapImageGetPixelRef(SkImage* rasterImage); +// Given an image created with NewPicture, return its SkPicture. +extern SkPicture* SkPictureImageGetPicture(SkImage* pictureImage); + // Given an image created with NewTexture, return its GrTexture. This // may be called to see if the surface and the image share the same GrTexture, // in which case the surface may need to perform a copy-on-write. -extern GrTexture* SkTextureImageGetTexture(SkImage* rasterImage); +extern GrTexture* SkTextureImageGetTexture(SkImage* textureImage); // Update the texture wrapped by an image created with NewTexture. This // is called when a surface and image share the same GrTexture and the diff --git a/src/image/SkImage_Picture.cpp b/src/image/SkImage_Picture.cpp index 447299f49d..be934fa238 100644 --- a/src/image/SkImage_Picture.cpp +++ b/src/image/SkImage_Picture.cpp @@ -16,6 +16,8 @@ public: virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) SK_OVERRIDE; + SkPicture* getPicture() { return fPicture; } + private: SkPicture* fPicture; @@ -52,3 +54,7 @@ SkImage* SkNewImageFromPicture(const SkPicture* srcPicture) { return SkNEW_ARGS(SkImage_Picture, (playback)); } + +SkPicture* SkPictureImageGetPicture(SkImage* pictureImage) { + return static_cast<SkImage_Picture*>(pictureImage)->getPicture(); +} diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index 1ed68e50b1..3c581c34e3 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -83,31 +83,24 @@ void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, canvas->drawBitmap(fDevice->accessBitmap(false), x, y, paint); } -// Copy the contents of the SkGpuDevice into a new texture and give that -// texture to the SkImage. Note that this flushes the SkGpuDevice but +// Create a new SkGpuDevice and, if necessary, copy the contents of the old +// device into it. Note that this flushes the SkGpuDevice but // doesn't force an OpenGL flush. -void SkSurface_Gpu::onCopyOnWrite(SkImage* image, SkCanvas*) { +void SkSurface_Gpu::onCopyOnWrite(SkImage* image, SkCanvas* canvas) { GrRenderTarget* rt = (GrRenderTarget*) fDevice->accessRenderTarget(); // are we sharing our render target with the image? if (rt->asTexture() == SkTextureImageGetTexture(image)) { - GrTextureDesc desc; - // copyTexture requires a render target as the destination - desc.fFlags = kRenderTarget_GrTextureFlagBit; - desc.fWidth = fDevice->width(); - desc.fHeight = fDevice->height(); - desc.fConfig = SkBitmapConfig2GrPixelConfig(fDevice->config()); - desc.fSampleCnt = 0; - - SkAutoTUnref<GrTexture> tex(fDevice->context()->createUncachedTexture(desc, NULL, 0)); - if (NULL == tex) { - SkTextureImageSetTexture(image, NULL); - return; - } - - fDevice->context()->copyTexture(rt->asTexture(), tex->asRenderTarget()); - - SkTextureImageSetTexture(image, tex); + SkGpuDevice* newDevice = static_cast<SkGpuDevice*>( + fDevice->createCompatibleDevice(fDevice->config(), fDevice->width(), + fDevice->height(), fDevice->isOpaque())); + SkAutoTUnref<SkGpuDevice> aurd(newDevice); + fDevice->context()->copyTexture(rt->asTexture(), + (GrRenderTarget*)newDevice->accessRenderTarget()); + SkASSERT(NULL != canvas); + SkASSERT(canvas->getDevice() == fDevice); + canvas->setDevice(newDevice); + SkRefCnt_SafeAssign(fDevice, newDevice); } } |