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
This commit is contained in:
parent
746cd0fc9a
commit
45c3db827d
@ -1023,6 +1023,7 @@ private:
|
||||
fSurfaceBase = sb;
|
||||
}
|
||||
friend class SkSurface_Base;
|
||||
friend class SkSurface_Gpu;
|
||||
|
||||
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
|
||||
void updateDeviceCMCache();
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user