aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar junov@chromium.org <junov@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-04-11 17:52:05 +0000
committerGravatar junov@chromium.org <junov@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-04-11 17:52:05 +0000
commit45c3db827d5bcb7c08bf49eff035be667332ec05 (patch)
treedd69e7516415b3501e549084f9f67cbf606313b3
parent746cd0fc9a83766db28b937d40ecea2c0aea1483 (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
-rw-r--r--include/core/SkCanvas.h1
-rw-r--r--src/image/SkImagePriv.h5
-rw-r--r--src/image/SkImage_Picture.cpp6
-rw-r--r--src/image/SkSurface_Gpu.cpp33
4 files changed, 24 insertions, 21 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 1e7e8280b2..930bdb6fbc 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -1023,6 +1023,7 @@ private:
fSurfaceBase = sb;
}
friend class SkSurface_Base;
+ friend class SkSurface_Gpu;
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
void updateDeviceCMCache();
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);
}
}