Chromium Code Reviews| Index: src/gpu/SkGpuDevice.cpp |
| diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp |
| index 1603cd64f1a9928e142d1ce5a2b8eb8480ab5b66..5b374a558476c1e621b08c72962587457a572625 100644 |
| --- a/src/gpu/SkGpuDevice.cpp |
| +++ b/src/gpu/SkGpuDevice.cpp |
| @@ -122,18 +122,62 @@ 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: |
|
robertphillips
2015/06/23 19:48:09
// If it is unpremul or unknown don't try to rende
bsalomon
2015/06/25 21:47:17
Done.
|
| + 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) { |
| + |
| + SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount)); |
| + if (NULL == rt) { |
| + return NULL; |
| + } |
| + |
|
robertphillips
2015/06/23 19:48:09
Should we change the alpha type & flags first ?
bsalomon
2015/06/25 21:47:17
Done.
|
| + unsigned flags; |
| + if (!CheckAlphaTypeAndGetFlags(&info, init, &flags)) { |
| + 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 +185,16 @@ 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); |
|
robertphillips
2015/06/23 19:48:09
Why do we need this ?
bsalomon
2015/06/25 21:47:17
oops, needed before I added the param to info().
|
| + if (fOpaque) { |
| + info = info.makeAlphaType(kOpaque_SkAlphaType); |
| + } |
| SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); |
| fLegacyBitmap.setInfo(info); |
| fLegacyBitmap.setPixelRef(pr)->unref(); |
| @@ -192,18 +241,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 +266,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 +368,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 +703,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 +746,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 +776,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 +1712,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 +1724,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", |