diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-03-30 18:29:01 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-03-30 18:29:01 +0000 |
commit | 18bbb8be02f3c4cd93cd4b2c1a5d744ac6854d8c (patch) | |
tree | 6d05d34044a38617dfe1a3696a06764f74a9ce93 | |
parent | 423d6d9070c99dacb46a8b5d120b348550316b01 (diff) |
Revet 3563 due to mac bot failure
git-svn-id: http://skia.googlecode.com/svn/trunk@3564 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/gpu/SkGpuDevice.h | 22 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 168 |
2 files changed, 83 insertions, 107 deletions
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h index ffc24a8c4b..409e3b30a5 100644 --- a/include/gpu/SkGpuDevice.h +++ b/include/gpu/SkGpuDevice.h @@ -29,11 +29,14 @@ class SK_API SkGpuDevice : public SkDevice { public: /** * New device that will create an offscreen renderTarget based on the - * config, width, height. The device's storage will not count against - * the GrContext's texture cache budget. The device's pixels will be - * uninitialized. + * config, width, height. + * + * usage is a special flag that should only be set by SkCanvas + * internally. */ - SkGpuDevice(GrContext*, SkBitmap::Config, int width, int height); + SkGpuDevice(GrContext*, SkBitmap::Config, + int width, int height, + SkDevice::Usage usage = SkDevice::kGeneral_Usage); /** * New device that will render to the specified renderTarget. @@ -115,8 +118,14 @@ public: protected: typedef GrContext::TextureCacheEntry TexCache; + enum TexType { + kBitmap_TexType, + kDeviceRenderTarget_TexType, + kSaveLayerDeviceRenderTarget_TexType + }; TexCache lockCachedTexture(const SkBitmap& bitmap, - const GrSamplerState* sampler); + const GrSamplerState* sampler, + TexType type = kBitmap_TexType); bool isBitmapInTextureCache(const SkBitmap& bitmap, const GrSamplerState& sampler) const; void unlockCachedTexture(TexCache); @@ -143,9 +152,6 @@ private: // called from rt and tex cons void initFromRenderTarget(GrContext*, GrRenderTarget*); - // used by createCompatibleDevice - SkGpuDevice(GrContext*, GrTexture* texture, TexCache, bool needClear); - // override from SkDevice virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, int width, int height, diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index b4656b92f5..e13a0ea990 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -22,7 +22,7 @@ #include "SkTLazy.h" #include "SkUtils.h" -#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 +#define CACHE_LAYER_TEXTURES 1 #if 0 extern bool (*gShouldDrawProc)(); @@ -30,11 +30,9 @@ do { \ if (gShouldDrawProc && !gShouldDrawProc()) return; \ this->prepareRenderTarget(draw); \ - GrAssert(!fNeedClear) \ } while (0) #else - #define CHECK_SHOULD_DRAW(draw) this->prepareRenderTarget(draw); \ - GrAssert(!fNeedClear) + #define CHECK_SHOULD_DRAW(draw) this->prepareRenderTarget(draw) #endif // we use the same texture slot on GrPaint for bitmaps and shaders @@ -61,15 +59,6 @@ enum { // requiring texture domain clamping to prevent color bleeding when drawing // a sub region of a larger source image. #define COLOR_BLEED_TOLERANCE SkFloatToScalar(0.001f) - -#define DO_DEFERRED_CLEAR \ - do { \ - if (fNeedClear) { \ - this->clear(NULL); \ - fNeedClear = false; \ - } \ - } while (false) \ - /////////////////////////////////////////////////////////////////////////////// class SkGpuDevice::SkAutoCachedTexture : public ::SkNoncopyable { @@ -204,11 +193,9 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context, fTextContext = NULL; } -SkGpuDevice::SkGpuDevice(GrContext* context, - SkBitmap::Config config, - int width, - int height) - : SkDevice(config, width, height, false /*isOpaque*/) { +SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width, + int height, Usage usage) +: SkDevice(config, width, height, false /*isOpaque*/) { fNeedPrepareRenderTarget = false; fDrawProcs = NULL; @@ -225,6 +212,19 @@ SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap bm; bm.setConfig(config, width, height); +#if CACHE_LAYER_TEXTURES + TexType type = (kSaveLayer_Usage == usage) ? + kSaveLayerDeviceRenderTarget_TexType : + kDeviceRenderTarget_TexType; + fCache = this->lockCachedTexture(bm, NULL, type); + fTexture = fCache.texture(); + if (fTexture) { + SkASSERT(NULL != fTexture->asRenderTarget()); + // hold a ref directly on fTexture (even though fCache has one) to match + // other constructor paths. Simplifies cleanup. + fTexture->ref(); + } +#else const GrTextureDesc desc = { kRenderTarget_GrTextureFlagBit, width, @@ -234,13 +234,16 @@ SkGpuDevice::SkGpuDevice(GrContext* context, }; fTexture = fContext->createUncachedTexture(desc, NULL, 0); - +#endif if (NULL != fTexture) { fRenderTarget = fTexture->asRenderTarget(); fRenderTarget->ref(); GrAssert(NULL != fRenderTarget); + // we defer the actual clear until our gainFocus() + fNeedClear = true; + // wrap the bitmap with a pixelref to expose our texture SkGrTexturePixelRef* pr = new SkGrTexturePixelRef(fTexture); this->setPixelRef(pr, 0)->unref(); @@ -275,7 +278,6 @@ SkGpuDevice::~SkGpuDevice() { /////////////////////////////////////////////////////////////////////////////// void SkGpuDevice::makeRenderTargetCurrent() { - DO_DEFERRED_CLEAR; fContext->setRenderTarget(fRenderTarget); fContext->flush(true); fNeedPrepareRenderTarget = true; @@ -308,7 +310,6 @@ GrPixelConfig config8888_to_gr_config(SkCanvas::Config8888 config8888) { bool SkGpuDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { - DO_DEFERRED_CLEAR; SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config()); SkASSERT(!bitmap.isNull()); SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()))); @@ -395,11 +396,13 @@ void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix, convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin()); - DO_DEFERRED_CLEAR; + if (fNeedClear) { + fContext->clear(NULL, 0x0); + fNeedClear = false; + } } SkGpuRenderTarget* SkGpuDevice::accessRenderTarget() { - DO_DEFERRED_CLEAR; return (SkGpuRenderTarget*)fRenderTarget; } @@ -593,7 +596,6 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev, /////////////////////////////////////////////////////////////////////////////// void SkGpuDevice::clear(SkColor color) { - fContext->setRenderTarget(fRenderTarget); fContext->clear(NULL, color); } @@ -1507,19 +1509,12 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, GR_Scalar1 * h / texture->height())); } -void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, +void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev, int x, int y, const SkPaint& paint) { - // clear of the source device must occur before CHECK_SHOULD_DRAW - SkGpuDevice* dev = static_cast<SkGpuDevice*>(dev); - if (dev->fNeedClear) { - // TODO: could check here whether we really need to draw at all - dev->clear(0x0); - } - CHECK_SHOULD_DRAW(draw); GrPaint grPaint; - if (!dev->bindDeviceAsTexture(&grPaint) || + if (!((SkGpuDevice*)dev)->bindDeviceAsTexture(&grPaint) || !skPaint2GrPaintNoShader(paint, true, false, &grPaint)) { return; } @@ -1814,35 +1809,55 @@ bool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { } void SkGpuDevice::flush() { - DO_DEFERRED_CLEAR; fContext->resolveRenderTarget(fRenderTarget); } /////////////////////////////////////////////////////////////////////////////// -SkGpuDevice::TexCache SkGpuDevice::lockCachedTexture( - const SkBitmap& bitmap, - const GrSamplerState* sampler) { +SkGpuDevice::TexCache SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap, + const GrSamplerState* sampler, + TexType type) { GrContext::TextureCacheEntry entry; GrContext* ctx = this->context(); - if (!bitmap.isVolatile()) { - GrContext::TextureKey key = bitmap.getGenerationID(); - key |= ((uint64_t) bitmap.pixelRefOffset()) << 32; - - entry = ctx->findAndLockTexture(key, bitmap.width(), - bitmap.height(), sampler); - if (NULL == entry.texture()) { - entry = sk_gr_create_bitmap_texture(ctx, key, sampler, - bitmap); + if (kBitmap_TexType != type) { + const GrTextureDesc desc = { + kRenderTarget_GrTextureFlagBit, + bitmap.width(), + bitmap.height(), + SkGr::Bitmap2PixelConfig(bitmap), + 0 // samples + }; + GrContext::ScratchTexMatch match; + if (kSaveLayerDeviceRenderTarget_TexType == type) { + // we know layers will only be drawn through drawDevice. + // drawDevice has been made to work with content embedded in a + // larger texture so its okay to use the approximate version. + match = GrContext::kApprox_ScratchTexMatch; + } else { + SkASSERT(kDeviceRenderTarget_TexType == type); + match = GrContext::kExact_ScratchTexMatch; } + entry = ctx->lockScratchTexture(desc, match); } else { - entry = sk_gr_create_bitmap_texture(ctx, gUNCACHED_KEY, - sampler, bitmap); - } - if (NULL == entry.texture()) { - GrPrintf("---- failed to create texture for cache [%d %d]\n", - bitmap.width(), bitmap.height()); + if (!bitmap.isVolatile()) { + GrContext::TextureKey key = bitmap.getGenerationID(); + key |= ((uint64_t) bitmap.pixelRefOffset()) << 32; + + entry = ctx->findAndLockTexture(key, bitmap.width(), + bitmap.height(), sampler); + if (NULL == entry.texture()) { + entry = sk_gr_create_bitmap_texture(ctx, key, sampler, + bitmap); + } + } else { + entry = sk_gr_create_bitmap_texture(ctx, gUNCACHED_KEY, + sampler, bitmap); + } + if (NULL == entry.texture()) { + GrPrintf("---- failed to create texture for cache [%d %d]\n", + bitmap.width(), bitmap.height()); + } } return entry; } @@ -1865,53 +1880,8 @@ SkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config, int width, int height, bool isOpaque, Usage usage) { - GrTextureDesc desc; - desc.fConfig = fRenderTarget->config(); - desc.fFlags = kRenderTarget_GrTextureFlagBit; - desc.fWidth = width; - desc.fHeight = height; - desc.fSampleCnt = fRenderTarget->numSamples(); - - GrContext::TextureCacheEntry cacheEntry; - GrTexture* texture; - SkAutoTUnref<GrTexture> tunref; - // Skia's convention is to only clear a device if it is a non-opaque layer. - bool needClear = !isOpaque && kSaveLayer_Usage == usage; - -#if CACHE_COMPATIBLE_DEVICE_TEXTURES - // layers are never draw in repeat modes, so we can request an approx - // match and ignore any padding. - GrContext::ScratchTexMatch matchType = (kSaveLayer_Usage == usage) ? - GrContext::kApprox_ScratchTexMatch : - GrContext::kExact_ScratchTexMatch; - cacheEntry = fContext->lockScratchTexture(desc, matchType); - texture = cacheEntry.texture(); -#else - tunref.reset(fContext->createUncachedTexture(desc, NULL, 0)); - texture = tunref.get(); -#endif - if (texture) { - return SkNEW_ARGS(SkGpuDevice,(fContext, - texture, - cacheEntry, - needClear)); - } else { - GrPrintf("---- failed to create compatible device texture [%d %d]\n", - width, height); - return NULL; - } -} - -SkGpuDevice::SkGpuDevice(GrContext* context, - GrTexture* texture, - TexCache cacheEntry, - bool needClear) - : SkDevice(make_bitmap(context, texture->asRenderTarget())) { - GrAssert(texture && texture->asRenderTarget()); - GrAssert(NULL == cacheEntry.texture() || texture == cacheEntry.texture()); - this->initFromRenderTarget(context, texture->asRenderTarget()); - fCache = cacheEntry; - fNeedClear = needClear; + return SkNEW_ARGS(SkGpuDevice,(this->context(), config, + width, height, usage)); } GrTextContext* SkGpuDevice::getTextContext() { |