diff options
author | 2015-01-16 07:32:33 -0800 | |
---|---|---|
committer | 2015-01-16 07:32:33 -0800 | |
commit | afe3005be3392e43bc51eb7eb2017eefaed85ad1 (patch) | |
tree | 3b96ec2e3249a928a0e876140bec3bf3e9dbb13f /src/gpu | |
parent | b50ced703030dfbda4fc3ef5e6ec9a52fc0405f8 (diff) |
Require budget decision when creating a RenderTarget SkSurface.
Restructure SkGpuDevice creation:
*SkSurfaceProps are optional.
*Use SkSurfaceProps to communicate DF text rather than a flag.
*Tell SkGpuDevice::Create whether RT comes from cache or not.
Review URL: https://codereview.chromium.org/848903004
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrGpuResource.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrGpuResourceCacheAccess.h | 6 | ||||
-rw-r--r-- | src/gpu/GrResourceCache2.cpp | 4 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 98 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.h | 39 |
5 files changed, 90 insertions, 65 deletions
diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp index a2df7e13e8..2f267a4197 100644 --- a/src/gpu/GrGpuResource.cpp +++ b/src/gpu/GrGpuResource.cpp @@ -6,7 +6,6 @@ * found in the LICENSE file. */ - #include "GrGpuResource.h" #include "GrResourceCache2.h" #include "GrGpu.h" @@ -134,6 +133,13 @@ void GrGpuResource::removeScratchKey() { } } +void GrGpuResource::makeBudgeted() { + if (GrGpuResource::kUncached_LifeCycle == fLifeCycle) { + fLifeCycle = kCached_LifeCycle; + get_resource_cache2(fGpu)->resourceAccess().didChangeBudgetStatus(this); + } +} + uint32_t GrGpuResource::CreateUniqueID() { static int32_t gUniqueID = SK_InvalidUniqueID; uint32_t id; diff --git a/src/gpu/GrGpuResourceCacheAccess.h b/src/gpu/GrGpuResourceCacheAccess.h index 0aadb89d97..d7c5028b20 100644 --- a/src/gpu/GrGpuResourceCacheAccess.h +++ b/src/gpu/GrGpuResourceCacheAccess.h @@ -70,6 +70,12 @@ public: bool isBudgeted() const { return GrGpuResource::kCached_LifeCycle == fResource->fLifeCycle; } /** + * If the resource is uncached make it cached. Has no effect on resources that are wrapped or + * already cached. + */ + void makeBudgeted() { fResource->makeBudgeted(); } + + /** * Called by the cache to delete the resource under normal circumstances. */ void release() { diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp index e23f9688ac..ba9d4d1016 100644 --- a/src/gpu/GrResourceCache2.cpp +++ b/src/gpu/GrResourceCache2.cpp @@ -306,6 +306,10 @@ void GrResourceCache2::didChangeBudgetStatus(GrGpuResource* resource) { if (resource->cacheAccess().isBudgeted()) { ++fBudgetedCount; fBudgetedBytes += size; +#if GR_CACHE_STATS + fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes); + fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount); +#endif this->purgeAsNeeded(); } else { --fBudgetedCount; diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 5f4713245e..e25cba5202 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -48,8 +48,6 @@ enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; -#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 - #if 0 extern bool (*gShouldDrawProc)(); #define CHECK_SHOULD_DRAW(draw) \ @@ -68,8 +66,8 @@ enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; #define DO_DEFERRED_CLEAR() \ do { \ - if (fFlags & kNeedClear_Flag) { \ - this->clearAll(); \ + if (fNeedClear) { \ + this->clearAll(); \ } \ } while (false) \ @@ -124,56 +122,71 @@ public: /////////////////////////////////////////////////////////////////////////////// -SkGpuDevice* SkGpuDevice::Create(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) { - SkASSERT(surface); - if (NULL == surface->asRenderTarget() || surface->wasDestroyed()) { +SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) { + if (!rt || rt->wasDestroyed()) { return NULL; } - return SkNEW_ARGS(SkGpuDevice, (surface, props, flags)); + return SkNEW_ARGS(SkGpuDevice, (rt, props, flags)); } -static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps& props) { - return SkDeviceProperties(props.pixelGeometry()); +static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* props) { + if (props) { + return SkDeviceProperties(props->pixelGeometry()); + } else { + return SkDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType); + } } -SkGpuDevice::SkGpuDevice(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) +static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) { + if (props) { + return SkSurfaceProps(*props); + } else { + return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType); + } +} + +SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) : INHERITED(surfaceprops_to_deviceprops(props)) + , fSurfaceProps(copy_or_default_props(props)) { fDrawProcs = NULL; - fContext = SkRef(surface->getContext()); - - fFlags = flags; + fContext = SkRef(rt->getContext()); + fNeedClear = flags & kNeedClear_Flag; - fRenderTarget = SkRef(surface->asRenderTarget()); + fRenderTarget = SkRef(rt); - SkImageInfo info = surface->surfacePriv().info(); - SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface)); + SkImageInfo info = rt->surfacePriv().info(); + SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); fLegacyBitmap.setInfo(info); fLegacyBitmap.setPixelRef(pr)->unref(); - bool useDFT = SkToBool(flags & kDFText_Flag); + bool useDFT = fSurfaceProps.isUseDistanceFieldFonts(); fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFT); } -SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo, - const SkSurfaceProps& props, int sampleCount) { +SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgeted, + const SkImageInfo& origInfo, int sampleCount, + const SkSurfaceProps* props, unsigned flags) { if (kUnknown_SkColorType == origInfo.colorType() || origInfo.width() < 0 || origInfo.height() < 0) { return NULL; } + if (!context) { + return NULL; + } + SkColorType ct = origInfo.colorType(); SkAlphaType at = origInfo.alphaType(); - // TODO: perhaps we can loosen this check now that colortype is more detailed - // e.g. can we support both RGBA and BGRA here? if (kRGB_565_SkColorType == ct) { at = kOpaque_SkAlphaType; // force this setting - } else { + } else if (ct != kBGRA_8888_SkColorType && ct != kRGBA_8888_SkColorType) { + // Fall back from whatever ct was to default of kRGBA or kBGRA which is aliased as kN32 ct = kN32_SkColorType; - if (kOpaque_SkAlphaType != at) { - at = kPremul_SkAlphaType; // force this setting - } + } + if (kOpaque_SkAlphaType != at) { + at = kPremul_SkAlphaType; // force this setting } const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at); @@ -184,12 +197,18 @@ SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo desc.fConfig = SkImageInfo2GrPixelConfig(info); desc.fSampleCnt = sampleCount; - SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0)); - if (!texture.get()) { + SkAutoTUnref<GrTexture> texture; + if (SkSurface::kYes_Budgeted == budgeted) { + texture.reset(context->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch)); + } else { + texture.reset(context->createUncachedTexture(desc, NULL, 0)); + } + + if (!texture) { return NULL; } - return SkNEW_ARGS(SkGpuDevice, (texture.get(), props)); + return SkNEW_ARGS(SkGpuDevice, (texture->asRenderTarget(), props, flags)); } SkGpuDevice::~SkGpuDevice() { @@ -295,7 +314,7 @@ void SkGpuDevice::clearAll() { GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clearAll", fContext); SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); fContext->clear(&rect, color, true, fRenderTarget); - fFlags &= ~kNeedClear_Flag; + fNeedClear = false; } /////////////////////////////////////////////////////////////////////////////// @@ -1517,7 +1536,7 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, // clear of the source device must occur before CHECK_SHOULD_DRAW GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext); SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); - if (dev->fFlags & kNeedClear_Flag) { + if (fNeedClear) { // TODO: could check here whether we really need to draw at all dev->clearAll(); } @@ -1800,21 +1819,17 @@ SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) { SkAutoTUnref<GrTexture> texture; // Skia's convention is to only clear a device if it is non-opaque. unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag; - // If we're using distance field text, enable in the new device - flags |= (fFlags & kDFText_Flag) ? kDFText_Flag : 0; -#if CACHE_COMPATIBLE_DEVICE_TEXTURES // layers are never draw in repeat modes, so we can request an approx // match and ignore any padding. const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == cinfo.fUsage) ? GrContext::kApprox_ScratchTexMatch : GrContext::kExact_ScratchTexMatch; texture.reset(fContext->refScratchTexture(desc, match)); -#else - texture.reset(fContext->createUncachedTexture(desc, NULL, 0)); -#endif - if (texture.get()) { - return SkGpuDevice::Create(texture, SkSurfaceProps(0, cinfo.fPixelGeometry), flags); + + if (texture) { + SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry); + return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags); } else { SkDebugf("---- failed to create compatible device texture [%d %d]\n", cinfo.fInfo.width(), cinfo.fInfo.height()); @@ -1823,7 +1838,10 @@ SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(const CreateInfo& cinfo) { } SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) { - return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(), &props); + // TODO: Change the signature of newSurface to take a budgeted parameter. + static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted; + return SkSurface::NewRenderTarget(fContext, kBudgeted, info, fRenderTarget->numSamples(), + &props); } bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* mainPicture, diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index 56dad1b475..6cbf628e58 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -6,8 +6,6 @@ * found in the LICENSE file. */ - - #ifndef SkGpuDevice_DEFINED #define SkGpuDevice_DEFINED @@ -16,6 +14,7 @@ #include "SkDevice.h" #include "SkPicture.h" #include "SkRegion.h" +#include "SkSurface.h" #include "GrContext.h" #include "GrSurfacePriv.h" @@ -34,25 +33,20 @@ class SK_API SkGpuDevice : public SkBaseDevice { public: enum Flags { kNeedClear_Flag = 1 << 0, //!< Surface requires an initial clear - kDFText_Flag = 1 << 1, //!< Surface should render text using signed distance fields }; /** - * Creates an SkGpuDevice from a GrSurface. This will fail if the surface is not a render - * target. The caller owns a ref on the returned device. If the surface is cached, - * the kCached_Flag should be specified to make the device responsible for unlocking - * the surface when it is released. + * Creates an SkGpuDevice from a GrRenderTarget. */ - static SkGpuDevice* Create(GrSurface* surface, const SkSurfaceProps&, unsigned flags = 0); + static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, unsigned flags = 0); /** - * New device that will create an offscreen renderTarget based on the - * ImageInfo and sampleCount. The device's storage will not - * count against the GrContext's texture cache budget. The device's pixels - * will be uninitialized. On failure, returns NULL. + * New device that will create an offscreen renderTarget based on the ImageInfo and + * sampleCount. The Budgeted param controls whether the device's backing store counts against + * the resource cache budget. On failure, returns NULL. */ - static SkGpuDevice* Create(GrContext*, const SkImageInfo&, const SkSurfaceProps&, - int sampleCount); + static SkGpuDevice* Create(GrContext*, SkSurface::Budgeted, const SkImageInfo&, + int sampleCount, const SkSurfaceProps*, unsigned flags = 0); virtual ~SkGpuDevice(); @@ -63,7 +57,7 @@ public: return static_cast<SkGpuDevice*>(dev); } - GrContext* context() const { return fContext; } + GrContext* context() const { return fRenderTarget->getContext(); } // set all pixels to 0 void clearAll(); @@ -74,6 +68,8 @@ public: return fRenderTarget ? fRenderTarget->surfacePriv().info() : SkImageInfo::MakeUnknown(); } + const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; } + void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, const SkPoint[], const SkPaint& paint) SK_OVERRIDE; @@ -139,21 +135,16 @@ protected: private: GrContext* fContext; - GrSkDrawProcs* fDrawProcs; - GrClipData fClipData; - GrTextContext* fTextContext; - - // state for our render-target + SkSurfaceProps fSurfaceProps; GrRenderTarget* fRenderTarget; - uint32_t fFlags; - // remove when our clients don't rely on accessBitmap() - SkBitmap fLegacyBitmap; + SkBitmap fLegacyBitmap; + bool fNeedClear; - SkGpuDevice(GrSurface*, const SkSurfaceProps&, unsigned flags = 0); + SkGpuDevice(GrRenderTarget*, const SkSurfaceProps*, unsigned flags); SkBaseDevice* onCreateCompatibleDevice(const CreateInfo&) SK_OVERRIDE; |