| Index: src/gpu/SkGpuDevice.cpp
|
| diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
|
| index 1603cd64f1a9928e142d1ce5a2b8eb8480ab5b66..d0f8d46ee89b87a10be354e11031c344950f67b9 100644
|
| --- a/src/gpu/SkGpuDevice.cpp
|
| +++ b/src/gpu/SkGpuDevice.cpp
|
| @@ -122,18 +122,61 @@ public:
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) {
|
| - return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, flags);
|
| +/** Checks that the alpha type is legal and gets constructor flags. Returns false if device creation
|
| + should fail. */
|
| +bool SkGpuDevice::CheckAlphaTypeAndGetFlags(
|
| + const SkImageInfo* info, SkGpuDevice::InitContents init, unsigned* flags) {
|
| + *flags = 0;
|
| + if (info) {
|
| + switch (info->alphaType()) {
|
| + case kPremul_SkAlphaType:
|
| + break;
|
| + case kOpaque_SkAlphaType:
|
| + *flags |= SkGpuDevice::kIsOpaque_Flag;
|
| + break;
|
| + default: // If it is unpremul or unknown don't try to render
|
| + return false;
|
| + }
|
| + }
|
| + if (kClear_InitContents == init) {
|
| + *flags |= kNeedClear_Flag;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props,
|
| + InitContents init) {
|
| + return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, init);
|
| }
|
|
|
| SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, int width, int height,
|
| - const SkSurfaceProps* props, unsigned flags) {
|
| + const SkSurfaceProps* props, InitContents init) {
|
| if (!rt || rt->wasDestroyed()) {
|
| return NULL;
|
| }
|
| + unsigned flags;
|
| + if (!CheckAlphaTypeAndGetFlags(NULL, init, &flags)) {
|
| + return NULL;
|
| + }
|
| return SkNEW_ARGS(SkGpuDevice, (rt, width, height, props, flags));
|
| }
|
|
|
| +SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgeted,
|
| + const SkImageInfo& info, int sampleCount,
|
| + const SkSurfaceProps* props, InitContents init) {
|
| + unsigned flags;
|
| + if (!CheckAlphaTypeAndGetFlags(&info, init, &flags)) {
|
| + return NULL;
|
| + }
|
| +
|
| + SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount));
|
| + if (NULL == rt) {
|
| + return NULL;
|
| + }
|
| +
|
| + return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flags));
|
| +}
|
| +
|
| SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height,
|
| const SkSurfaceProps* props, unsigned flags)
|
| : INHERITED(SkSurfacePropsCopyOrDefault(props))
|
| @@ -141,11 +184,13 @@ SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height,
|
| fDrawProcs = NULL;
|
|
|
| fContext = SkRef(rt->getContext());
|
| - fNeedClear = flags & kNeedClear_Flag;
|
| + fNeedClear = SkToBool(flags & kNeedClear_Flag);
|
| + fOpaque = SkToBool(flags & kIsOpaque_Flag);
|
|
|
| fRenderTarget = SkRef(rt);
|
|
|
| - SkImageInfo info = rt->surfacePriv().info().makeWH(width, height);
|
| + SkAlphaType at = fOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
|
| + SkImageInfo info = rt->surfacePriv().info(at).makeWH(width, height);
|
| SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
|
| fLegacyBitmap.setInfo(info);
|
| fLegacyBitmap.setPixelRef(pr)->unref();
|
| @@ -192,18 +237,6 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::B
|
| return texture->asRenderTarget();
|
| }
|
|
|
| -SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgeted,
|
| - const SkImageInfo& info, int sampleCount,
|
| - const SkSurfaceProps* props, unsigned flags) {
|
| -
|
| - SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount));
|
| - if (NULL == rt) {
|
| - return NULL;
|
| - }
|
| -
|
| - return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flags));
|
| -}
|
| -
|
| SkGpuDevice::~SkGpuDevice() {
|
| if (fDrawProcs) {
|
| delete fDrawProcs;
|
| @@ -229,8 +262,8 @@ bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
|
| if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
|
| flags = GrContext::kUnpremul_PixelOpsFlag;
|
| }
|
| - return fContext->readRenderTargetPixels(fRenderTarget, x, y, dstInfo.width(), dstInfo.height(),
|
| - config, dstPixels, dstRowBytes, flags);
|
| + return fRenderTarget->readPixels(x, y, dstInfo.width(), dstInfo.height(), config, dstPixels,
|
| + dstRowBytes, flags);
|
| }
|
|
|
| bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
|
| @@ -331,8 +364,12 @@ void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) {
|
| fRenderTarget->unref();
|
| fRenderTarget = newRT.detach();
|
|
|
| - SkASSERT(fRenderTarget->surfacePriv().info() == fLegacyBitmap.info());
|
| - SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fRenderTarget->surfacePriv().info(), fRenderTarget));
|
| +#ifdef SK_DEBUG
|
| + SkImageInfo info = fRenderTarget->surfacePriv().info(fOpaque ? kOpaque_SkAlphaType :
|
| + kPremul_SkAlphaType);
|
| + SkASSERT(info == fLegacyBitmap.info());
|
| +#endif
|
| + SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fLegacyBitmap.info(), fRenderTarget));
|
| fLegacyBitmap.setPixelRef(pr)->unref();
|
|
|
| fDrawContext.reset(SkRef(fRenderTarget->getContext()->drawContext(&this->surfaceProps())));
|
| @@ -662,8 +699,7 @@ static int determine_tile_size(const SkBitmap& bitmap, const SkIRect& src, int m
|
|
|
| // Given a bitmap, an optional src rect, and a context with a clip and matrix determine what
|
| // pixels from the bitmap are necessary.
|
| -static void determine_clipped_src_rect(const GrContext* context,
|
| - const GrRenderTarget* rt,
|
| +static void determine_clipped_src_rect(const GrRenderTarget* rt,
|
| const GrClip& clip,
|
| const SkMatrix& viewMatrix,
|
| const SkBitmap& bitmap,
|
| @@ -706,7 +742,7 @@ bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
|
|
|
| // if it's larger than the max tile size, then we have no choice but tiling.
|
| if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
|
| - determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap,
|
| + determine_clipped_src_rect(fRenderTarget, fClip, viewMatrix, bitmap,
|
| srcRectPtr, clippedSrcRect);
|
| *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
|
| return true;
|
| @@ -736,7 +772,7 @@ bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
|
| }
|
|
|
| // Figure out how much of the src we will need based on the src rect and clipping.
|
| - determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap, srcRectPtr,
|
| + determine_clipped_src_rect(fRenderTarget, fClip, viewMatrix, bitmap, srcRectPtr,
|
| clippedSrcRect);
|
| *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
|
| size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
|
| @@ -1672,7 +1708,7 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
|
|
|
| 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;
|
| + InitContents init = cinfo.fInfo.isOpaque() ? kUninit_InitContents : kClear_InitContents;
|
|
|
| // layers are never draw in repeat modes, so we can request an approx
|
| // match and ignore any padding.
|
| @@ -1684,7 +1720,7 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
|
| if (texture) {
|
| SkSurfaceProps props(this->surfaceProps().flags(), cinfo.fPixelGeometry);
|
| return SkGpuDevice::Create(
|
| - texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height(), &props, flags);
|
| + texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height(), &props, init);
|
| } else {
|
| SkErrorInternals::SetError( kInternalError_SkError,
|
| "---- failed to create gpu device texture [%d %d]\n",
|
|
|