diff --git a/gyp/tests.gypi b/gyp/tests.gypi index d45c535582..4bed2a9adc 100644 --- a/gyp/tests.gypi +++ b/gyp/tests.gypi @@ -119,6 +119,7 @@ '../tests/ImageDecodingTest.cpp', '../tests/ImageFilterTest.cpp', '../tests/ImageGeneratorTest.cpp', + '../tests/ImageIsOpaqueTest.cpp', '../tests/ImageNewShaderTest.cpp', '../tests/InfRectTest.cpp', '../tests/InterpolatorTest.cpp', diff --git a/include/core/SkImage.h b/include/core/SkImage.h index 1316e2b595..1f275149b8 100644 --- a/include/core/SkImage.h +++ b/include/core/SkImage.h @@ -48,6 +48,8 @@ public: */ static SkImage* NewTexture(const SkBitmap&); + virtual bool isOpaque() const { return false; } + /** * Construct a new SkImage based on the given ImageGenerator. * This function will always take ownership of the passed diff --git a/src/image/SkImage_Codec.cpp b/src/image/SkImage_Codec.cpp index 21c844d01d..0b14216a06 100644 --- a/src/image/SkImage_Codec.cpp +++ b/src/image/SkImage_Codec.cpp @@ -22,6 +22,8 @@ public: virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&, const SkPaint*) const SK_OVERRIDE; + virtual bool isOpaque() const SK_OVERRIDE; + private: SkData* fEncodedData; SkBitmap fBitmap; @@ -78,3 +80,8 @@ SkImage* SkImage::NewEncodedData(SkData* data) { return SkNEW_ARGS(SkImage_Codec, (data, bitmap.width(), bitmap.height())); } + + +bool SkImage_Codec::isOpaque() const { + return fBitmap.isOpaque(); +} diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 0918412e83..d98a5367a6 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -31,6 +31,9 @@ public: virtual SkShader* onNewShader(SkShader::TileMode, SkShader::TileMode, const SkMatrix* localMatrix) const SK_OVERRIDE; + + virtual bool isOpaque() const SK_OVERRIDE; + private: SkBitmap fBitmap; @@ -72,6 +75,10 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst) const { return fBitmap.copyTo(dst, kN32_SkColorType); } +bool SkImage_Gpu::isOpaque() const { + return fBitmap.isOpaque(); +} + /////////////////////////////////////////////////////////////////////////////// SkImage* SkImage::NewTexture(const SkBitmap& bitmap) { diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp index a1cd602a07..a7e4e009e5 100644 --- a/src/image/SkImage_Raster.cpp +++ b/src/image/SkImage_Raster.cpp @@ -70,6 +70,8 @@ public: SkShader::TileMode, const SkMatrix* localMatrix) const SK_OVERRIDE; + virtual bool isOpaque() const SK_OVERRIDE; + SkImage_Raster(const SkBitmap& bm) : INHERITED(bm.width(), bm.height()) , fBitmap(bm) {} @@ -219,3 +221,7 @@ SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) { return ((SkImage_Raster*)image)->getPixelRef(); } + +bool SkImage_Raster::isOpaque() const { + return fBitmap.isOpaque(); +} diff --git a/tests/ImageIsOpaqueTest.cpp b/tests/ImageIsOpaqueTest.cpp new file mode 100644 index 0000000000..902e24d827 --- /dev/null +++ b/tests/ImageIsOpaqueTest.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkTypes.h" +#if SK_SUPPORT_GPU +#include "GrContextFactory.h" +#endif +#include "SkImage.h" +#include "SkSurface.h" + +#include "Test.h" + +DEF_TEST(ImageIsOpaqueTest, reporter) { + SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5); + SkAutoTUnref surfaceTransparent(SkSurface::NewRaster(infoTransparent)); + REPORTER_ASSERT(reporter, !surfaceTransparent->newImageSnapshot()->isOpaque()); + + SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType); + SkAutoTUnref surfaceOpaque(SkSurface::NewRaster(infoOpaque)); + REPORTER_ASSERT(reporter, surfaceOpaque->newImageSnapshot()->isOpaque()); +} + +#if SK_SUPPORT_GPU + +DEF_GPUTEST(ImageIsOpaqueTest_GPU, reporter, factory) { + for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) { + GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i; + + if (!GrContextFactory::IsRenderingGLContext(glCtxType)) { + continue; + } + + GrContext* context = factory->get(glCtxType); + + if (NULL == context) { + continue; + } + + SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5); + SkAutoTUnref surfaceTransparent(SkSurface::NewRenderTarget(context, infoTransparent)); + REPORTER_ASSERT(reporter, !surfaceTransparent->newImageSnapshot()->isOpaque()); + + SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType); + SkAutoTUnref surfaceOpaque(SkSurface::NewRenderTarget(context, infoOpaque)); + REPORTER_ASSERT(reporter, !surfaceOpaque->newImageSnapshot()->isOpaque()); + + } +} + +#endif