diff options
author | 2015-06-23 14:38:48 -0700 | |
---|---|---|
committer | 2015-06-23 14:38:48 -0700 | |
commit | 74f681dce2fbadd481596aea15afb3e0fb36ceff (patch) | |
tree | 86093c4896eeddbbc33283288fbebb21996fce13 | |
parent | 5fbb623099a6d0e0e72e7e230e75014fd64ae240 (diff) |
Make SkGpuDevice know its alpha type
Make SkImage_Gpu snapshots opaque if surface is opaque.
BUG=skia:3965
Review URL: https://codereview.chromium.org/1205643002
-rw-r--r-- | include/gpu/GrSurface.h | 2 | ||||
-rw-r--r-- | src/gpu/GrLayerHoister.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrSurface.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrSurfacePriv.h | 6 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 90 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.h | 20 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 2 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 8 | ||||
-rw-r--r-- | tests/ImageFilterTest.cpp | 12 | ||||
-rw-r--r-- | tests/PremulAlphaRoundTripTest.cpp | 3 | ||||
-rw-r--r-- | tests/ReadWriteAlphaTest.cpp | 3 | ||||
-rw-r--r-- | tests/SurfaceTest.cpp | 65 | ||||
-rw-r--r-- | tools/PictureRenderer.cpp | 4 |
13 files changed, 154 insertions, 67 deletions
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h index 4d40e2e814..123ab1b3c7 100644 --- a/include/gpu/GrSurface.h +++ b/include/gpu/GrSurface.h @@ -137,7 +137,7 @@ public: protected: // Methods made available via GrSurfacePriv - SkImageInfo info() const; + SkImageInfo info(SkAlphaType) const; bool savePixels(const char* filename); bool hasPendingRead() const; bool hasPendingWrite() const; diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp index 1f01e1a983..e1aa72c83d 100644 --- a/src/gpu/GrLayerHoister.cpp +++ b/src/gpu/GrLayerHoister.cpp @@ -281,7 +281,7 @@ SkBitmap wrap_texture(GrTexture* texture) { SkASSERT(texture); SkBitmap result; - result.setInfo(texture->surfacePriv().info()); + result.setInfo(texture->surfacePriv().info(kPremul_SkAlphaType)); result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref(); return result; } diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp index c052a235f0..b304ccb1dd 100644 --- a/src/gpu/GrSurface.cpp +++ b/src/gpu/GrSurface.cpp @@ -41,13 +41,13 @@ bool GrSurface::readPixels(int left, int top, int width, int height, return false; } -SkImageInfo GrSurface::info() const { +SkImageInfo GrSurface::info(SkAlphaType alphaType) const { SkColorType colorType; SkColorProfileType profileType; if (!GrPixelConfig2ColorAndProfileType(this->config(), &colorType, &profileType)) { sk_throw(); } - return SkImageInfo::Make(this->width(), this->height(), colorType, kPremul_SkAlphaType, + return SkImageInfo::Make(this->width(), this->height(), colorType, alphaType, profileType); } diff --git a/src/gpu/GrSurfacePriv.h b/src/gpu/GrSurfacePriv.h index cd1f6b92ba..47bd44f4ef 100644 --- a/src/gpu/GrSurfacePriv.h +++ b/src/gpu/GrSurfacePriv.h @@ -18,10 +18,10 @@ class GrSurfacePriv { public: /** - * Derive a SkImageInfo from the surface's descriptor. This is lossy as ImageInfo has fields not - * known to GrSurface (e.g. alphaType). + * Derive a SkImageInfo from the surface's descriptor. The caller must provide the alpha type as + * GrSurface has no equivalent. */ - SkImageInfo info() const { return fSurface->info(); } + SkImageInfo info(SkAlphaType alphaType) const { return fSurface->info(alphaType); } /** * Write the contents of the surface to a PNG. Returns true if successful. diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 1603cd64f1..d0f8d46ee8 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", diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index f71450d7c9..9fa756c29a 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -30,21 +30,22 @@ struct GrCachedLayer; */ class SK_API SkGpuDevice : public SkBaseDevice { public: - enum Flags { - kNeedClear_Flag = 1 << 0, //!< Surface requires an initial clear + enum InitContents { + kClear_InitContents, + kUninit_InitContents }; /** * Creates an SkGpuDevice from a GrRenderTarget. */ - static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, unsigned flags = 0); + static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, InitContents); /** * Creates an SkGpuDevice from a GrRenderTarget whose texture width/height is * different than its actual width/height (e.g., approx-match scratch texture). */ static SkGpuDevice* Create(GrRenderTarget* target, int width, int height, - const SkSurfaceProps*, unsigned flags = 0); + const SkSurfaceProps*, InitContents); /** * New device that will create an offscreen renderTarget based on the ImageInfo and @@ -52,7 +53,7 @@ public: * the resource cache budget. On failure, returns NULL. */ static SkGpuDevice* Create(GrContext*, SkSurface::Budgeted, const SkImageInfo&, - int sampleCount, const SkSurfaceProps*, unsigned flags = 0); + int sampleCount, const SkSurfaceProps*, InitContents); virtual ~SkGpuDevice(); @@ -153,6 +154,15 @@ private: // remove when our clients don't rely on accessBitmap() SkBitmap fLegacyBitmap; bool fNeedClear; + bool fOpaque; + + enum Flags { + kNeedClear_Flag = 1 << 0, //!< Surface requires an initial clear + kIsOpaque_Flag = 1 << 1, //!< Hint from client that rendering to this device will be + // opaque even if the config supports alpha. + }; + static bool CheckAlphaTypeAndGetFlags(const SkImageInfo* info, InitContents init, + unsigned* flags); SkGpuDevice(GrRenderTarget*, int width, int height, const SkSurfaceProps*, unsigned flags); diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 973f4ba304..4003631c8a 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -61,7 +61,7 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst) const { } bool SkImage_Gpu::isOpaque() const { - return GrPixelConfigIsOpaque(fTexture->config()); + return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaque_SkAlphaType; } static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) { diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index cbc183eacf..fa006a61cd 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -83,7 +83,8 @@ void SkSurface_Gpu::onDiscard() { /////////////////////////////////////////////////////////////////////////////// SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) { - SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, props)); + SkAutoTUnref<SkGpuDevice> device( + SkGpuDevice::Create(target, props, SkGpuDevice::kUninit_InitContents)); if (!device) { return NULL; } @@ -93,7 +94,7 @@ SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurf SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info, int sampleCount, const SkSurfaceProps* props) { SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props, - SkGpuDevice::kNeedClear_Flag)); + SkGpuDevice::kClear_InitContents)); if (!device) { return NULL; } @@ -113,7 +114,8 @@ SkSurface* SkSurface::NewWrappedRenderTarget(GrContext* context, GrBackendTextur if (!surface) { return NULL; } - SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props)); + SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props, + SkGpuDevice::kUninit_InitContents)); if (!device) { return NULL; } diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp index 9bdd910f1b..480a75fe1d 100644 --- a/tests/ImageFilterTest.cpp +++ b/tests/ImageFilterTest.cpp @@ -1152,7 +1152,8 @@ DEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) { SkSurface::kNo_Budgeted, SkImageInfo::MakeN32Premul(100, 100), 0, - &props)); + &props, + SkGpuDevice::kUninit_InitContents)); SkImageFilter::Proxy proxy(device); test_crop_rects(&proxy, reporter); @@ -1169,7 +1170,8 @@ DEF_GPUTEST(HugeBlurImageFilterGPU, reporter, factory) { SkSurface::kNo_Budgeted, SkImageInfo::MakeN32Premul(100, 100), 0, - &props)); + &props, + SkGpuDevice::kUninit_InitContents)); SkCanvas canvas(device); test_huge_blur(&canvas, reporter); @@ -1186,7 +1188,8 @@ DEF_GPUTEST(XfermodeImageFilterCroppedInputGPU, reporter, factory) { SkSurface::kNo_Budgeted, SkImageInfo::MakeN32Premul(1, 1), 0, - &props)); + &props, + SkGpuDevice::kUninit_InitContents)); SkCanvas canvas(device); test_xfermode_cropped_input(&canvas, reporter); @@ -1203,7 +1206,8 @@ DEF_GPUTEST(TestNegativeBlurSigmaGPU, reporter, factory) { SkSurface::kNo_Budgeted, SkImageInfo::MakeN32Premul(1, 1), 0, - &props)); + &props, + SkGpuDevice::kUninit_InitContents)); SkImageFilter::Proxy proxy(device); test_negative_blur_sigma(&proxy, reporter); diff --git a/tests/PremulAlphaRoundTripTest.cpp b/tests/PremulAlphaRoundTripTest.cpp index e48885c930..e230f11025 100644 --- a/tests/PremulAlphaRoundTripTest.cpp +++ b/tests/PremulAlphaRoundTripTest.cpp @@ -90,7 +90,8 @@ DEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) { if (NULL == ctx) { continue; } - device.reset(SkGpuDevice::Create(ctx, SkSurface::kNo_Budgeted, info, 0, &props)); + device.reset(SkGpuDevice::Create(ctx, SkSurface::kNo_Budgeted, info, 0, &props, + SkGpuDevice::kUninit_InitContents)); #else continue; #endif diff --git a/tests/ReadWriteAlphaTest.cpp b/tests/ReadWriteAlphaTest.cpp index 6ae77d0411..a767068622 100644 --- a/tests/ReadWriteAlphaTest.cpp +++ b/tests/ReadWriteAlphaTest.cpp @@ -83,7 +83,8 @@ DEF_GPUTEST(ReadWriteAlpha, reporter, factory) { // Now try writing on the single channel texture SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType); - SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props)); + SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props, + SkGpuDevice::kUninit_InitContents)); SkCanvas canvas(device); SkPaint paint; diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp index 0114fb66fc..cfaa669262 100644 --- a/tests/SurfaceTest.cpp +++ b/tests/SurfaceTest.cpp @@ -30,16 +30,20 @@ enum SurfaceType { kRasterDirect_SurfaceType, kGpu_SurfaceType, kGpuScratch_SurfaceType, + + kLastSurfaceType = kGpuScratch_SurfaceType }; +static const int kSurfaceTypeCnt = kLastSurfaceType + 1; static void release_storage(void* pixels, void* context) { SkASSERT(pixels == context); sk_free(pixels); } -static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context, - SkImageInfo* requestedInfo = NULL) { - static const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); +static SkSurface* create_surface(SurfaceType surfaceType, GrContext* context, + SkAlphaType at = kPremul_SkAlphaType, + SkImageInfo* requestedInfo = NULL) { + const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at); if (requestedInfo) { *requestedInfo = info; @@ -219,8 +223,8 @@ struct ReleaseDataContext { } }; -static SkImage* createImage(ImageType imageType, GrContext* context, SkColor color, - ReleaseDataContext* releaseContext) { +static SkImage* create_image(ImageType imageType, GrContext* context, SkColor color, + ReleaseDataContext* releaseContext) { const SkPMColor pmcolor = SkPreMultiplyColor(color); const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); const size_t rowBytes = info.minRowBytes(); @@ -347,7 +351,7 @@ static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* facto size_t rowBytes; releaseCtx.fData = NULL; - SkAutoTUnref<SkImage> image(createImage(gRec[i].fType, ctx, color, &releaseCtx)); + SkAutoTUnref<SkImage> image(create_image(gRec[i].fType, ctx, color, &releaseCtx)); if (!image.get()) { SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName); continue; // gpu may not be enabled @@ -417,8 +421,8 @@ static void test_canvaspeek(skiatest::Reporter* reporter, SkImageInfo info, requestInfo; size_t rowBytes; - SkAutoTUnref<SkSurface> surface(createSurface(gRec[i].fType, context, - &requestInfo)); + SkAutoTUnref<SkSurface> surface(create_surface(gRec[i].fType, context, + kPremul_SkAlphaType, &requestInfo)); surface->getCanvas()->clear(color); const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes); @@ -484,8 +488,8 @@ static void test_accessPixels(skiatest::Reporter* reporter, GrContextFactory* fa for (size_t j = 0; j < SK_ARRAY_COUNT(gRec); ++j) { SkImageInfo info, requestInfo; - SkAutoTUnref<SkSurface> surface(createSurface(gRec[j].fType, context, - &requestInfo)); + SkAutoTUnref<SkSurface> surface(create_surface(gRec[j].fType, context, + kPremul_SkAlphaType, &requestInfo)); SkCanvas* canvas = surface->getCanvas(); canvas->clear(0); @@ -501,10 +505,35 @@ static void test_accessPixels(skiatest::Reporter* reporter, GrContextFactory* fa } } +static void test_snap_alphatype(skiatest::Reporter* reporter, GrContextFactory* factory) { + GrContext* context = NULL; +#if SK_SUPPORT_GPU + context = factory->get(GrContextFactory::kNative_GLContextType); + if (NULL == context) { + return; + } +#endif + for (int opaque = 0; opaque < 2; ++opaque) { + SkAlphaType atype = SkToBool(opaque) ? kOpaque_SkAlphaType : kPremul_SkAlphaType; + for (int st = 0; st < kSurfaceTypeCnt; ++st) { + SurfaceType stype = (SurfaceType)st; + SkAutoTUnref<SkSurface> surface(create_surface(stype, context, atype)); + REPORTER_ASSERT(reporter, surface); + if (surface) { + SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); + REPORTER_ASSERT(reporter, image); + if (image) { + REPORTER_ASSERT(reporter, image->isOpaque() == SkToBool(opaque)); + } + } + } + } +} + static void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType surfaceType, GrContext* context) { // Verify that the right canvas commands trigger a copy on write - SkSurface* surface = createSurface(surfaceType, context); + SkSurface* surface = create_surface(surfaceType, context); SkAutoTUnref<SkSurface> aur_surface(surface); SkCanvas* canvas = surface->getCanvas(); @@ -587,7 +616,7 @@ static void TestSurfaceWritableAfterSnapshotRelease(skiatest::Reporter* reporter // This test succeeds by not triggering an assertion. // The test verifies that the surface remains writable (usable) after // acquiring and releasing a snapshot without triggering a copy on write. - SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context)); + SkAutoTUnref<SkSurface> surface(create_surface(surfaceType, context)); SkCanvas* canvas = surface->getCanvas(); canvas->clear(1); surface->newImageSnapshot()->unref(); // Create and destroy SkImage @@ -602,8 +631,8 @@ static void Test_crbug263329(skiatest::Reporter* reporter, // Bug was caused by onCopyOnWrite releasing the old surface texture // back to the scratch texture pool even though the texture is used // by and active SkImage_Gpu. - SkAutoTUnref<SkSurface> surface1(createSurface(surfaceType, context)); - SkAutoTUnref<SkSurface> surface2(createSurface(surfaceType, context)); + SkAutoTUnref<SkSurface> surface1(create_surface(surfaceType, context)); + SkAutoTUnref<SkSurface> surface2(create_surface(surfaceType, context)); SkCanvas* canvas1 = surface1->getCanvas(); SkCanvas* canvas2 = surface2->getCanvas(); canvas1->clear(1); @@ -633,7 +662,7 @@ static void Test_crbug263329(skiatest::Reporter* reporter, static void TestGetTexture(skiatest::Reporter* reporter, SurfaceType surfaceType, GrContext* context) { - SkAutoTUnref<SkSurface> surface(createSurface(surfaceType, context)); + SkAutoTUnref<SkSurface> surface(create_surface(surfaceType, context)); SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); GrTexture* texture = as_IB(image)->getTexture(); if (surfaceType == kGpu_SurfaceType || surfaceType == kGpuScratch_SurfaceType) { @@ -700,13 +729,13 @@ static void TestSurfaceNoCanvas(skiatest::Reporter* reporter, // are made before a canvas is created. { // Test passes by not asserting - SkSurface* surface = createSurface(surfaceType, context); + SkSurface* surface = create_surface(surfaceType, context); SkAutoTUnref<SkSurface> aur_surface(surface); surface->notifyContentWillChange(mode); SkDEBUGCODE(surface->validate();) } { - SkSurface* surface = createSurface(surfaceType, context); + SkSurface* surface = create_surface(surfaceType, context); SkAutoTUnref<SkSurface> aur_surface(surface); SkImage* image1 = surface->newImageSnapshot(); SkAutoTUnref<SkImage> aur_image1(image1); @@ -740,6 +769,8 @@ DEF_GPUTEST(Surface, reporter, factory) { test_accessPixels(reporter, factory); + test_snap_alphatype(reporter, factory); + #if SK_SUPPORT_GPU TestGetTexture(reporter, kRaster_SurfaceType, NULL); if (factory) { diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp index 270b61fd28..34b08f567c 100644 --- a/tools/PictureRenderer.cpp +++ b/tools/PictureRenderer.cpp @@ -159,7 +159,9 @@ SkCanvas* PictureRenderer::setupCanvas(int width, int height) { uint32_t flags = fUseDFText ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0; SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); - SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target->asRenderTarget(), &props)); + SkAutoTUnref<SkGpuDevice> device( + SkGpuDevice::Create(target->asRenderTarget(), &props, + SkGpuDevice::kUninit_InitContents)); if (!device) { return NULL; } |