aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dm/DM.cpp61
-rwxr-xr-xsrc/gpu/GrContextFactory.cpp23
-rw-r--r--src/gpu/GrContextFactory.h48
-rw-r--r--tests/ImageTest.cpp70
-rw-r--r--tests/SurfaceTest.cpp658
-rw-r--r--tests/Test.h42
-rw-r--r--tests/TestTest.cpp75
7 files changed, 573 insertions, 404 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 8873dcabbe..7497161369 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -1144,6 +1144,67 @@ int dm_main() {
return 0;
}
+// TODO: currently many GPU tests are declared outside SK_SUPPORT_GPU guards.
+// Thus we export the empty RunWithGPUTestContexts when SK_SUPPORT_GPU=0.
+namespace skiatest {
+namespace {
+typedef void(*TestWithGrContext)(skiatest::Reporter*, GrContext*);
+typedef void(*TestWithGrContextAndGLContext)(skiatest::Reporter*, GrContext*, SkGLContext*);
+#if SK_SUPPORT_GPU
+template<typename T>
+void call_test(T test, skiatest::Reporter* reporter, GrContextFactory::ContextInfo* context);
+template<>
+void call_test(TestWithGrContext test, skiatest::Reporter* reporter,
+ GrContextFactory::ContextInfo* context) {
+ test(reporter, context->fGrContext);
+}
+template<>
+void call_test(TestWithGrContextAndGLContext test, skiatest::Reporter* reporter,
+ GrContextFactory::ContextInfo* context) {
+ test(reporter, context->fGrContext, context->fGLContext);
+}
+#endif
+} // namespace
+
+
+template<typename T>
+void RunWithGPUTestContexts(T test, GPUTestContexts testContexts, Reporter* reporter,
+ GrContextFactory* factory) {
+#if SK_SUPPORT_GPU
+ for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
+ GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
+ int contextSelector = kNone_GPUTestContexts;
+ if (GrContextFactory::IsRenderingGLContext(glCtxType)) {
+ contextSelector |= kAllRendering_GPUTestContexts;
+ }
+ if (glCtxType == GrContextFactory::kNative_GLContextType) {
+ contextSelector |= kNative_GPUTestContexts;
+ }
+ if (glCtxType == GrContextFactory::kNull_GLContextType) {
+ contextSelector |= kNull_GPUTestContexts;
+ }
+ if ((testContexts & contextSelector) == 0) {
+ continue;
+ }
+ if (GrContextFactory::ContextInfo* context = factory->getContextInfo(glCtxType)) {
+ call_test(test, reporter, context);
+ }
+ }
+#endif
+}
+
+template
+void RunWithGPUTestContexts<TestWithGrContext>(TestWithGrContext test,
+ GPUTestContexts testContexts,
+ Reporter* reporter,
+ GrContextFactory* factory);
+template
+void RunWithGPUTestContexts<TestWithGrContextAndGLContext>(TestWithGrContextAndGLContext test,
+ GPUTestContexts testContexts,
+ Reporter* reporter,
+ GrContextFactory* factory);
+} // namespace skiatest
+
#if !defined(SK_BUILD_FOR_IOS)
int main(int argc, char** argv) {
SkCommandLineFlags::Parse(argc, argv);
diff --git a/src/gpu/GrContextFactory.cpp b/src/gpu/GrContextFactory.cpp
index acd5d93a04..424b3fda3a 100755
--- a/src/gpu/GrContextFactory.cpp
+++ b/src/gpu/GrContextFactory.cpp
@@ -23,15 +23,16 @@
#include "gl/GrGLGpu.h"
#include "GrCaps.h"
-GrContext* GrContextFactory::get(GLContextType type, GrGLStandard forcedGpuAPI) {
+GrContextFactory::ContextInfo* GrContextFactory::getContextInfo(GLContextType type,
+ GrGLStandard forcedGpuAPI) {
for (int i = 0; i < fContexts.count(); ++i) {
if (forcedGpuAPI != kNone_GrGLStandard &&
- forcedGpuAPI != fContexts[i].fGLContext->gl()->fStandard)
+ forcedGpuAPI != fContexts[i]->fGLContext->gl()->fStandard)
continue;
- if (fContexts[i].fType == type) {
- fContexts[i].fGLContext->makeCurrent();
- return fContexts[i].fGrContext;
+ if (fContexts[i]->fType == type) {
+ fContexts[i]->fGLContext->makeCurrent();
+ return fContexts[i];
}
}
SkAutoTUnref<SkGLContext> glCtx;
@@ -114,11 +115,9 @@ GrContext* GrContextFactory::get(GLContextType type, GrGLStandard forcedGpuAPI)
}
}
- GPUContext& ctx = fContexts.push_back();
- ctx.fGLContext = glCtx.get();
- ctx.fGLContext->ref();
- ctx.fGrContext = grCtx.get();
- ctx.fGrContext->ref();
- ctx.fType = type;
- return ctx.fGrContext;
+ ContextInfo* ctx = fContexts.emplace_back(new ContextInfo);
+ ctx->fGLContext = SkRef(glCtx.get());
+ ctx->fGrContext = SkRef(grCtx.get());
+ ctx->fType = type;
+ return ctx;
}
diff --git a/src/gpu/GrContextFactory.h b/src/gpu/GrContextFactory.h
index 130c333dd0..6d17432318 100644
--- a/src/gpu/GrContextFactory.h
+++ b/src/gpu/GrContextFactory.h
@@ -98,39 +98,52 @@ public:
void destroyContexts() {
for (int i = 0; i < fContexts.count(); ++i) {
- if (fContexts[i].fGLContext) { // could be abandoned.
- fContexts[i].fGLContext->makeCurrent();
- }
- fContexts[i].fGrContext->unref();
- if (fContexts[i].fGLContext) {
- fContexts[i].fGLContext->unref();
+ if (fContexts[i]->fGLContext) { // could be abandoned.
+ fContexts[i]->fGLContext->makeCurrent();
}
+ fContexts[i]->fGrContext->unref();
+ SkSafeUnref(fContexts[i]->fGLContext);
}
fContexts.reset();
}
void abandonContexts() {
for (int i = 0; i < fContexts.count(); ++i) {
- if (fContexts[i].fGLContext) {
- fContexts[i].fGLContext->testAbandon();
- SkSafeSetNull(fContexts[i].fGLContext);
+ if (fContexts[i]->fGLContext) {
+ fContexts[i]->fGLContext->testAbandon();
+ SkSafeSetNull(fContexts[i]->fGLContext);
}
- fContexts[i].fGrContext->abandonContext();
+ fContexts[i]->fGrContext->abandonContext();
}
}
+ struct ContextInfo {
+ GLContextType fType;
+ SkGLContext* fGLContext;
+ GrContext* fGrContext;
+ };
/**
- * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
+ * Get a context initialized with a type of GL context. It also makes the GL context current.
+ * Pointer is valid until destroyContexts() is called.
*/
- GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard);
+ ContextInfo* getContextInfo(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard);
+ /**
+ * Get a GrContext initialized with a type of GL context. It also makes the GL context current.
+ */
+ GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard) {
+ if (ContextInfo* info = this->getContextInfo(type, forcedGpuAPI)) {
+ return info->fGrContext;
+ }
+ return nullptr;
+ }
// Returns the GLContext of the given type. If it has not been created yet,
// nullptr is returned instead.
SkGLContext* getGLContext(GLContextType type) {
for (int i = 0; i < fContexts.count(); ++i) {
- if (fContexts[i].fType == type) {
- return fContexts[i].fGLContext;
+ if (fContexts[i]->fType == type) {
+ return fContexts[i]->fGLContext;
}
}
@@ -140,12 +153,7 @@ public:
const GrContextOptions& getGlobalOptions() const { return fGlobalOptions; }
private:
- struct GPUContext {
- GLContextType fType;
- SkGLContext* fGLContext;
- GrContext* fGrContext;
- };
- SkTArray<GPUContext, true> fContexts;
+ SkTArray<SkAutoTDelete<ContextInfo>, true> fContexts;
const GrContextOptions fGlobalOptions;
};
diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp
index d139ca7075..7bce8e5a5d 100644
--- a/tests/ImageTest.cpp
+++ b/tests/ImageTest.cpp
@@ -415,60 +415,6 @@ struct ReleaseDataContext {
}
};
-// May we (soon) eliminate the need to keep testing this, by hiding the bloody device!
-#include "SkDevice.h"
-static uint32_t get_legacy_gen_id(SkSurface* surf) {
- SkBaseDevice* device = surf->getCanvas()->getDevice_just_for_deprecated_compatibility_testing();
- return device->accessBitmap(false).getGenerationID();
-}
-
-/*
- * Test legacy behavor of bumping the surface's device's bitmap's genID when we access its
- * texture handle for writing.
- *
- * Note: this needs to be tested separately from checking newImageSnapshot, as calling that
- * can also incidentally bump the genID (when a new backing surface is created).
- */
-template <class F>
-static void test_texture_handle_genID(skiatest::Reporter* reporter, SkSurface* surf, F f) {
- const uint32_t gen0 = get_legacy_gen_id(surf);
- f(surf, SkSurface::kFlushRead_BackendHandleAccess);
- const uint32_t gen1 = get_legacy_gen_id(surf);
- REPORTER_ASSERT(reporter, gen0 == gen1);
-
- f(surf, SkSurface::kFlushWrite_BackendHandleAccess);
- const uint32_t gen2 = get_legacy_gen_id(surf);
- REPORTER_ASSERT(reporter, gen0 != gen2);
-
- f(surf, SkSurface::kDiscardWrite_BackendHandleAccess);
- const uint32_t gen3 = get_legacy_gen_id(surf);
- REPORTER_ASSERT(reporter, gen0 != gen3);
- REPORTER_ASSERT(reporter, gen2 != gen3);
-}
-
-template <class F>
-static void test_backend_handle(skiatest::Reporter* reporter, SkSurface* surf, F f) {
- SkAutoTUnref<SkImage> image0(surf->newImageSnapshot());
- GrBackendObject obj = f(surf, SkSurface::kFlushRead_BackendHandleAccess);
- REPORTER_ASSERT(reporter, obj != 0);
- SkAutoTUnref<SkImage> image1(surf->newImageSnapshot());
- // just read access should not affect the snapshot
- REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID());
-
- obj = f(surf, SkSurface::kFlushWrite_BackendHandleAccess);
- REPORTER_ASSERT(reporter, obj != 0);
- SkAutoTUnref<SkImage> image2(surf->newImageSnapshot());
- // expect a new image, since we claimed we would write
- REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID());
-
- obj = f(surf, SkSurface::kDiscardWrite_BackendHandleAccess);
- REPORTER_ASSERT(reporter, obj != 0);
- SkAutoTUnref<SkImage> image3(surf->newImageSnapshot());
- // expect a new(er) image, since we claimed we would write
- REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID());
- REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID());
-}
-
static SkImage* create_image(skiatest::Reporter* reporter,
ImageType imageType, GrContext* context, SkColor color,
ReleaseDataContext* releaseContext) {
@@ -495,22 +441,6 @@ static SkImage* create_image(skiatest::Reporter* reporter,
SkAutoTUnref<SkSurface> surf(
SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0));
surf->getCanvas()->clear(color);
- // test our backing texture / rendertarget while were here...
- auto textureAccessorFunc =
- [](SkSurface* surf, SkSurface::BackendHandleAccess access) -> GrBackendObject {
- return surf->getTextureHandle(access); };
- auto renderTargetAccessorFunc =
- [](SkSurface* surf, SkSurface::BackendHandleAccess access) -> GrBackendObject {
- GrBackendObject obj;
- SkAssertResult(surf->getRenderTargetHandle(&obj, access));
- return obj; };
- test_backend_handle(reporter, surf, textureAccessorFunc);
- test_backend_handle(reporter, surf, renderTargetAccessorFunc);
- test_texture_handle_genID(reporter, surf, textureAccessorFunc);
- test_texture_handle_genID(reporter, surf, renderTargetAccessorFunc);
-
- // redraw so our returned image looks as expected.
- surf->getCanvas()->clear(color);
return surf->newImageSnapshot();
}
case kCodec_ImageType: {
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 7e07e17f89..6859bce6bc 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -8,7 +8,6 @@
#include "SkCanvas.h"
#include "SkData.h"
#include "SkDevice.h"
-#include "SkImageEncoder.h"
#include "SkImage_Base.h"
#include "SkPath.h"
#include "SkRRect.h"
@@ -17,72 +16,73 @@
#include "Test.h"
#if SK_SUPPORT_GPU
-#include "GrContextFactory.h"
-#include "GrTest.h"
-#else
-class GrContextFactory;
-class GrContext;
+#include "GrContext.h"
+#include "GrGpu.h"
#endif
-enum SurfaceType {
- kRaster_SurfaceType,
- kRasterDirect_SurfaceType,
- kGpu_SurfaceType,
- kGpuScratch_SurfaceType,
+#include <initializer_list>
- kLastSurfaceType = kGpuScratch_SurfaceType
-};
-static const int kSurfaceTypeCnt = kLastSurfaceType + 1;
-
-static void release_storage(void* pixels, void* context) {
+static void release_direct_surface_storage(void* pixels, void* context) {
SkASSERT(pixels == context);
sk_free(pixels);
}
-
-static SkSurface* create_surface(SurfaceType surfaceType, GrContext* context,
- SkAlphaType at = kPremul_SkAlphaType,
+static SkSurface* create_surface(SkAlphaType at = kPremul_SkAlphaType,
SkImageInfo* requestedInfo = nullptr) {
const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
-
if (requestedInfo) {
*requestedInfo = info;
}
-
- switch (surfaceType) {
- case kRaster_SurfaceType:
- return SkSurface::NewRaster(info);
- case kRasterDirect_SurfaceType: {
- const size_t rowBytes = info.minRowBytes();
- void* storage = sk_malloc_throw(info.getSafeSize(rowBytes));
- return SkSurface::NewRasterDirectReleaseProc(info, storage, rowBytes,
- release_storage, storage);
- }
- case kGpu_SurfaceType:
- return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0, nullptr);
- case kGpuScratch_SurfaceType:
- return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted, info, 0, nullptr);
+ return SkSurface::NewRaster(info);
+}
+static SkSurface* create_direct_surface(SkAlphaType at = kPremul_SkAlphaType,
+ SkImageInfo* requestedInfo = nullptr) {
+ const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
+ if (requestedInfo) {
+ *requestedInfo = info;
+ }
+ const size_t rowBytes = info.minRowBytes();
+ void* storage = sk_malloc_throw(info.getSafeSize(rowBytes));
+ return SkSurface::NewRasterDirectReleaseProc(info, storage, rowBytes,
+ release_direct_surface_storage,
+ storage);
+}
+#if SK_SUPPORT_GPU
+static SkSurface* create_gpu_surface(GrContext* context, SkAlphaType at = kPremul_SkAlphaType,
+ SkImageInfo* requestedInfo = nullptr) {
+ const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
+ if (requestedInfo) {
+ *requestedInfo = info;
+ }
+ return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0, nullptr);
+}
+static SkSurface* create_gpu_scratch_surface(GrContext* context,
+ SkAlphaType at = kPremul_SkAlphaType,
+ SkImageInfo* requestedInfo = nullptr) {
+ const SkImageInfo info = SkImageInfo::MakeN32(10, 10, at);
+ if (requestedInfo) {
+ *requestedInfo = info;
}
- return nullptr;
+ return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted, info, 0, nullptr);
}
+#endif
-static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) {
+DEF_TEST(SurfaceEmpty, reporter) {
const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
-
REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRaster(info));
REPORTER_ASSERT(reporter, nullptr == SkSurface::NewRasterDirect(info, nullptr, 0));
- if (ctx) {
- REPORTER_ASSERT(reporter, nullptr ==
- SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info, 0, nullptr));
- }
-}
+}
#if SK_SUPPORT_GPU
-static void test_wrapped_texture_surface(skiatest::Reporter* reporter, GrContext* ctx) {
- if (nullptr == ctx) {
- return;
- }
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, context) {
+ const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
+ REPORTER_ASSERT(reporter, nullptr ==
+ SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0, nullptr));
+}
+#endif
- const GrGpu* gpu = ctx->getGpu();
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceWrappedTexture, reporter, context) {
+ const GrGpu* gpu = context->getGpu();
if (!gpu) {
return;
}
@@ -106,7 +106,8 @@ static void test_wrapped_texture_surface(skiatest::Reporter* reporter, GrContext
wrappedDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
wrappedDesc.fTextureHandle = texHandle;
- SkAutoTUnref<SkSurface> surface(SkSurface::NewWrappedRenderTarget(ctx, wrappedDesc, nullptr));
+ SkAutoTUnref<SkSurface> surface(
+ SkSurface::NewWrappedRenderTarget(context, wrappedDesc, nullptr));
REPORTER_ASSERT(reporter, surface);
if (surface) {
// Validate that we can draw to the canvas and that the original texture color is preserved
@@ -146,165 +147,136 @@ static void test_wrapped_texture_surface(skiatest::Reporter* reporter, GrContext
}
}
gpu->deleteTestingOnlyBackendTexture(texHandle);
-
}
#endif
-
-
-static void test_canvaspeek(skiatest::Reporter* reporter,
- GrContextFactory* factory) {
- static const struct {
- SurfaceType fType;
- bool fPeekShouldSucceed;
- } gRec[] = {
- { kRaster_SurfaceType, true },
- { kRasterDirect_SurfaceType, true },
-#if SK_SUPPORT_GPU
- { kGpu_SurfaceType, false },
- { kGpuScratch_SurfaceType, false },
-#endif
- };
-
+static void test_canvas_peek(skiatest::Reporter* reporter,
+ SkSurface* surface,
+ const SkImageInfo& requestInfo,
+ bool expectPeekSuccess) {
const SkColor color = SK_ColorRED;
const SkPMColor pmcolor = SkPreMultiplyColor(color);
-
- int cnt;
-#if SK_SUPPORT_GPU
- cnt = GrContextFactory::kGLContextTypeCnt;
-#else
- cnt = 1;
-#endif
-
- for (int i= 0; i < cnt; ++i) {
- GrContext* context = nullptr;
+ SkImageInfo info;
+ size_t rowBytes;
+ surface->getCanvas()->clear(color);
+
+ const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes);
+ bool success = SkToBool(addr);
+ REPORTER_ASSERT(reporter, expectPeekSuccess == success);
+
+ SkImageInfo info2;
+ size_t rb2;
+ const void* addr2 = surface->peekPixels(&info2, &rb2);
+
+ if (success) {
+ REPORTER_ASSERT(reporter, requestInfo == info);
+ REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= rowBytes);
+ REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
+
+ REPORTER_ASSERT(reporter, addr2 == addr);
+ REPORTER_ASSERT(reporter, info2 == info);
+ REPORTER_ASSERT(reporter, rb2 == rowBytes);
+ } else {
+ REPORTER_ASSERT(reporter, nullptr == addr2);
+ }
+}
+DEF_TEST(SurfaceCanvasPeek, reporter) {
+ for (auto& surface_func : { &create_surface, &create_direct_surface }) {
+ SkImageInfo requestInfo;
+ SkAutoTUnref<SkSurface> surface(surface_func(kPremul_SkAlphaType, &requestInfo));
+ test_canvas_peek(reporter, surface, requestInfo, true);
+ }
+}
#if SK_SUPPORT_GPU
- GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
- if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
- continue;
- }
- context = factory->get(glCtxType);
-
- if (nullptr == context) {
- continue;
- }
-#endif
- for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
- SkImageInfo info, requestInfo;
- size_t rowBytes;
-
- SkAutoTUnref<SkSurface> surface(create_surface(gRec[i].fType, context,
- kPremul_SkAlphaType, &requestInfo));
- surface->getCanvas()->clear(color);
-
- const void* addr = surface->getCanvas()->peekPixels(&info, &rowBytes);
- bool success = SkToBool(addr);
- REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
-
- SkImageInfo info2;
- size_t rb2;
- const void* addr2 = surface->peekPixels(&info2, &rb2);
-
- if (success) {
- REPORTER_ASSERT(reporter, requestInfo == info);
- REPORTER_ASSERT(reporter, requestInfo.minRowBytes() <= rowBytes);
- REPORTER_ASSERT(reporter, pmcolor == *(const SkPMColor*)addr);
-
- REPORTER_ASSERT(reporter, addr2 == addr);
- REPORTER_ASSERT(reporter, info2 == info);
- REPORTER_ASSERT(reporter, rb2 == rowBytes);
- } else {
- REPORTER_ASSERT(reporter, nullptr == addr2);
- }
- }
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCanvasPeek_Gpu, reporter, context) {
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ SkImageInfo requestInfo;
+ SkAutoTUnref<SkSurface> surface(surface_func(context, kPremul_SkAlphaType, &requestInfo));
+ test_canvas_peek(reporter, surface, requestInfo, false);
}
}
+#endif
// For compatibility with clients that still call accessBitmap(), we need to ensure that we bump
// the bitmap's genID when we draw to it, else they won't know it has new values. When they are
// exclusively using surface/image, and we can hide accessBitmap from device, we can remove this
// test.
-static void test_accessPixels(skiatest::Reporter* reporter, GrContextFactory* factory) {
- static const struct {
- SurfaceType fType;
- bool fPeekShouldSucceed;
- } gRec[] = {
- { kRaster_SurfaceType, true },
- { kRasterDirect_SurfaceType, true },
-#if SK_SUPPORT_GPU
- { kGpu_SurfaceType, false },
- { kGpuScratch_SurfaceType, false },
-#endif
- };
-
- int cnt;
+void test_access_pixels(skiatest::Reporter* reporter, SkSurface* surface) {
+ SkCanvas* canvas = surface->getCanvas();
+ canvas->clear(0);
+
+ SkBaseDevice* device = canvas->getDevice_just_for_deprecated_compatibility_testing();
+ SkBitmap bm = device->accessBitmap(false);
+ uint32_t genID0 = bm.getGenerationID();
+ // Now we draw something, which needs to "dirty" the genID (sorta like copy-on-write)
+ canvas->drawColor(SK_ColorBLUE);
+ // Now check that we get a different genID
+ uint32_t genID1 = bm.getGenerationID();
+ REPORTER_ASSERT(reporter, genID0 != genID1);
+}
+DEF_TEST(SurfaceAccessPixels, reporter) {
+ for (auto& surface_func : { &create_surface, &create_direct_surface }) {
+ SkAutoTUnref<SkSurface> surface(surface_func(kPremul_SkAlphaType, nullptr));
+ test_access_pixels(reporter, surface);
+ }
+}
#if SK_SUPPORT_GPU
- cnt = GrContextFactory::kGLContextTypeCnt;
-#else
- cnt = 1;
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceAccessPixels_Gpu, reporter, context) {
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ SkAutoTUnref<SkSurface> surface(surface_func(context, kPremul_SkAlphaType, nullptr));
+ test_access_pixels(reporter, surface);
+ }
+}
#endif
-
- for (int i= 0; i < cnt; ++i) {
- GrContext* context = nullptr;
-#if SK_SUPPORT_GPU
- GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
- if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
- continue;
- }
- context = factory->get(glCtxType);
-
- if (nullptr == context) {
- continue;
+
+static void test_snapshot_alphatype(skiatest::Reporter* reporter, SkSurface* surface,
+ bool expectOpaque) {
+ REPORTER_ASSERT(reporter, surface);
+ if (surface) {
+ SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
+ REPORTER_ASSERT(reporter, image);
+ if (image) {
+ REPORTER_ASSERT(reporter, image->isOpaque() == SkToBool(expectOpaque));
}
-#endif
- for (size_t j = 0; j < SK_ARRAY_COUNT(gRec); ++j) {
- SkImageInfo info, requestInfo;
-
- SkAutoTUnref<SkSurface> surface(create_surface(gRec[j].fType, context,
- kPremul_SkAlphaType, &requestInfo));
- SkCanvas* canvas = surface->getCanvas();
- canvas->clear(0);
-
- SkBaseDevice* device = canvas->getDevice_just_for_deprecated_compatibility_testing();
- SkBitmap bm = device->accessBitmap(false);
- uint32_t genID0 = bm.getGenerationID();
- // Now we draw something, which needs to "dirty" the genID (sorta like copy-on-write)
- canvas->drawColor(SK_ColorBLUE);
- // Now check that we get a different genID
- uint32_t genID1 = bm.getGenerationID();
- REPORTER_ASSERT(reporter, genID0 != genID1);
+ }
+}
+DEF_TEST(SurfaceSnapshotAlphaType, reporter) {
+ for (auto& surface_func : { &create_surface, &create_direct_surface }) {
+ for (auto& isOpaque : { true, false }) {
+ SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
+ SkAutoTUnref<SkSurface> surface(surface_func(alphaType, nullptr));
+ test_snapshot_alphatype(reporter, surface, isOpaque);
}
}
}
-
-static void test_snap_alphatype(skiatest::Reporter* reporter, GrContextFactory* factory) {
- GrContext* context = nullptr;
#if SK_SUPPORT_GPU
- context = factory->get(GrContextFactory::kNative_GLContextType);
- if (nullptr == context) {
- return;
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceSnapshotAlphaType_Gpu, reporter, context) {
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ for (auto& isOpaque : { true, false }) {
+ SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
+ SkAutoTUnref<SkSurface> surface(surface_func(context, alphaType, nullptr));
+ test_snapshot_alphatype(reporter, surface, isOpaque);
+ }
}
+}
#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 GrBackendObject get_surface_backend_texture_handle(
+ SkSurface* s, SkSurface::BackendHandleAccess a) {
+ return s->getTextureHandle(a);
+}
+static GrBackendObject get_surface_backend_render_target_handle(
+ SkSurface* s, SkSurface::BackendHandleAccess a) {
+ GrBackendObject result;
+ if (!s->getRenderTargetHandle(&result, a)) {
+ return 0;
}
+ return result;
}
-static void test_backend_cow(skiatest::Reporter* reporter, SkSurface* surface,
- SkSurface::BackendHandleAccess mode,
- GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) {
+static void test_backend_handle_access_copy_on_write(
+ skiatest::Reporter* reporter, SkSurface* surface, SkSurface::BackendHandleAccess mode,
+ GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) {
GrBackendObject obj1 = func(surface, mode);
SkAutoTUnref<SkImage> snap1(surface->newImageSnapshot());
@@ -314,12 +286,113 @@ static void test_backend_cow(skiatest::Reporter* reporter, SkSurface* surface,
// If the access mode triggers CoW, then the backend objects should reflect it.
REPORTER_ASSERT(reporter, (obj1 == obj2) == (snap1 == snap2));
}
+DEF_TEST(SurfaceBackendHandleAccessCopyOnWrite, reporter) {
+ const SkSurface::BackendHandleAccess accessModes[] = {
+ SkSurface::kFlushRead_BackendHandleAccess,
+ SkSurface::kFlushWrite_BackendHandleAccess,
+ SkSurface::kDiscardWrite_BackendHandleAccess,
+ };
+ for (auto& handle_access_func :
+ { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle }) {
+ for (auto& accessMode : accessModes) {
+ SkAutoTUnref<SkSurface> surface(create_surface());
+ test_backend_handle_access_copy_on_write(reporter, surface, accessMode,
+ handle_access_func);
+ }
+ }
+}
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessCopyOnWrite_Gpu, reporter, context) {
+ const SkSurface::BackendHandleAccess accessModes[] = {
+ SkSurface::kFlushRead_BackendHandleAccess,
+ SkSurface::kFlushWrite_BackendHandleAccess,
+ SkSurface::kDiscardWrite_BackendHandleAccess,
+ };
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ for (auto& handle_access_func :
+ { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle }) {
+ for (auto& accessMode : accessModes) {
+ SkAutoTUnref<SkSurface> surface(surface_func(context, kPremul_SkAlphaType,
+ nullptr));
+ test_backend_handle_access_copy_on_write(reporter, surface, accessMode,
+ handle_access_func);
+ }
+ }
+ }
+}
+#endif
-static void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType surfaceType,
- GrContext* context) {
- // Verify that the right canvas commands trigger a copy on write
- SkSurface* surface = create_surface(surfaceType, context);
- SkAutoTUnref<SkSurface> aur_surface(surface);
+#if SK_SUPPORT_GPU
+// May we (soon) eliminate the need to keep testing this, by hiding the bloody device!
+static uint32_t get_legacy_gen_id(SkSurface* surface) {
+ SkBaseDevice* device =
+ surface->getCanvas()->getDevice_just_for_deprecated_compatibility_testing();
+ return device->accessBitmap(false).getGenerationID();
+}
+/*
+ * Test legacy behavor of bumping the surface's device's bitmap's genID when we access its
+ * texture handle for writing.
+ *
+ * Note: this needs to be tested separately from checking newImageSnapshot, as calling that
+ * can also incidentally bump the genID (when a new backing surface is created).
+ */
+static void test_backend_handle_gen_id(
+ skiatest::Reporter* reporter, SkSurface* surface,
+ GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) {
+ const uint32_t gen0 = get_legacy_gen_id(surface);
+ func(surface, SkSurface::kFlushRead_BackendHandleAccess);
+ const uint32_t gen1 = get_legacy_gen_id(surface);
+ REPORTER_ASSERT(reporter, gen0 == gen1);
+
+ func(surface, SkSurface::kFlushWrite_BackendHandleAccess);
+ const uint32_t gen2 = get_legacy_gen_id(surface);
+ REPORTER_ASSERT(reporter, gen0 != gen2);
+
+ func(surface, SkSurface::kDiscardWrite_BackendHandleAccess);
+ const uint32_t gen3 = get_legacy_gen_id(surface);
+ REPORTER_ASSERT(reporter, gen0 != gen3);
+ REPORTER_ASSERT(reporter, gen2 != gen3);
+}
+static void test_backend_handle_unique_id(
+ skiatest::Reporter* reporter, SkSurface* surface,
+ GrBackendObject (*func)(SkSurface*, SkSurface::BackendHandleAccess)) {
+ SkAutoTUnref<SkImage> image0(surface->newImageSnapshot());
+ GrBackendObject obj = func(surface, SkSurface::kFlushRead_BackendHandleAccess);
+ REPORTER_ASSERT(reporter, obj != 0);
+ SkAutoTUnref<SkImage> image1(surface->newImageSnapshot());
+ // just read access should not affect the snapshot
+ REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID());
+
+ obj = func(surface, SkSurface::kFlushWrite_BackendHandleAccess);
+ REPORTER_ASSERT(reporter, obj != 0);
+ SkAutoTUnref<SkImage> image2(surface->newImageSnapshot());
+ // expect a new image, since we claimed we would write
+ REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID());
+
+ obj = func(surface, SkSurface::kDiscardWrite_BackendHandleAccess);
+ REPORTER_ASSERT(reporter, obj != 0);
+ SkAutoTUnref<SkImage> image3(surface->newImageSnapshot());
+ // expect a new(er) image, since we claimed we would write
+ REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID());
+ REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID());
+}
+// No CPU test.
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBackendHandleAccessIDs_Gpu, reporter, context) {
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ for (auto& test_func : { &test_backend_handle_unique_id, &test_backend_handle_gen_id }) {
+ for (auto& handle_access_func :
+ { &get_surface_backend_texture_handle, &get_surface_backend_render_target_handle}) {
+ SkAutoTUnref<SkSurface> surface(surface_func(context, kPremul_SkAlphaType,
+ nullptr));
+ test_func(reporter, surface, handle_access_func);
+ }
+ }
+ }
+}
+#endif
+
+// Verify that the right canvas commands trigger a copy on write.
+static void test_copy_on_write(skiatest::Reporter* reporter, SkSurface* surface) {
SkCanvas* canvas = surface->getCanvas();
const SkRect testRect =
@@ -393,53 +466,51 @@ static void TestSurfaceCopyOnWrite(skiatest::Reporter* reporter, SurfaceType sur
testPaint))
EXPECT_COPY_ON_WRITE(drawTextOnPath(testText.c_str(), testText.size(), testPath, nullptr, \
testPaint))
-
- const SkSurface::BackendHandleAccess accessModes[] = {
- SkSurface::kFlushRead_BackendHandleAccess,
- SkSurface::kFlushWrite_BackendHandleAccess,
- SkSurface::kDiscardWrite_BackendHandleAccess,
- };
-
- for (auto access : accessModes) {
- test_backend_cow(reporter, surface, access,
- [](SkSurface* s, SkSurface::BackendHandleAccess a) -> GrBackendObject {
- return s->getTextureHandle(a);
- });
-
- test_backend_cow(reporter, surface, access,
- [](SkSurface* s, SkSurface::BackendHandleAccess a) -> GrBackendObject {
- GrBackendObject result;
- if (!s->getRenderTargetHandle(&result, a)) {
- return 0;
- }
- return result;
- });
+}
+DEF_TEST(SurfaceCopyOnWrite, reporter) {
+ SkAutoTUnref<SkSurface> surface(create_surface());
+ test_copy_on_write(reporter, surface);
+}
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCopyOnWrite_Gpu, reporter, context) {
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ SkAutoTUnref<SkSurface> surface(surface_func(context, kPremul_SkAlphaType, nullptr));
+ test_copy_on_write(reporter, surface);
}
}
+#endif
-static void TestSurfaceWritableAfterSnapshotRelease(skiatest::Reporter* reporter,
- SurfaceType surfaceType,
- GrContext* context) {
+static void test_writable_after_snapshot_release(skiatest::Reporter* reporter,
+ SkSurface* surface) {
// 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(create_surface(surfaceType, context));
SkCanvas* canvas = surface->getCanvas();
canvas->clear(1);
surface->newImageSnapshot()->unref(); // Create and destroy SkImage
canvas->clear(2); // Must not assert internally
}
+DEF_TEST(SurfaceWriteableAfterSnapshotRelease, reporter) {
+ SkAutoTUnref<SkSurface> surface(create_surface());
+ test_writable_after_snapshot_release(reporter, surface);
+}
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceWriteableAfterSnapshotRelease_Gpu, reporter, context) {
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ SkAutoTUnref<SkSurface> surface(surface_func(context, kPremul_SkAlphaType, nullptr));
+ test_writable_after_snapshot_release(reporter, surface);
+ }
+}
+#endif
#if SK_SUPPORT_GPU
-static void Test_crbug263329(skiatest::Reporter* reporter,
- SurfaceType surfaceType,
- GrContext* context) {
+static void test_crbug263329(skiatest::Reporter* reporter,
+ SkSurface* surface1,
+ SkSurface* surface2) {
// This is a regression test for crbug.com/263329
// 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(create_surface(surfaceType, context));
- SkAutoTUnref<SkSurface> surface2(create_surface(surfaceType, context));
SkCanvas* canvas1 = surface1->getCanvas();
SkCanvas* canvas2 = surface2->getCanvas();
canvas1->clear(1);
@@ -465,39 +536,53 @@ static void Test_crbug263329(skiatest::Reporter* reporter,
REPORTER_ASSERT(reporter, as_IB(image3)->getTexture() != as_IB(image1)->getTexture());
REPORTER_ASSERT(reporter, as_IB(image2)->getTexture() != as_IB(image1)->getTexture());
}
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceCRBug263329_Gpu, reporter, context) {
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ SkAutoTUnref<SkSurface> surface1(surface_func(context, kPremul_SkAlphaType, nullptr));
+ SkAutoTUnref<SkSurface> surface2(surface_func(context, kPremul_SkAlphaType, nullptr));
+ test_crbug263329(reporter, surface1, surface2);
+ }
+}
+#endif
-static void TestGetTexture(skiatest::Reporter* reporter,
- SurfaceType surfaceType,
- GrContext* context) {
- SkAutoTUnref<SkSurface> surface(create_surface(surfaceType, context));
+DEF_TEST(SurfaceGetTexture, reporter) {
+ SkAutoTUnref<SkSurface> surface(create_surface());
SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
- GrTexture* texture = as_IB(image)->getTexture();
- if (surfaceType == kGpu_SurfaceType || surfaceType == kGpuScratch_SurfaceType) {
+ REPORTER_ASSERT(reporter, as_IB(image)->getTexture() == nullptr);
+ surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
+ REPORTER_ASSERT(reporter, as_IB(image)->getTexture() == nullptr);
+}
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceGetTexture_Gpu, reporter, context) {
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ SkAutoTUnref<SkSurface> surface(surface_func(context, kPremul_SkAlphaType, nullptr));
+ SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
+ GrTexture* texture = as_IB(image)->getTexture();
REPORTER_ASSERT(reporter, texture);
REPORTER_ASSERT(reporter, 0 != texture->getTextureHandle());
- } else {
- REPORTER_ASSERT(reporter, nullptr == texture);
+ surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
+ REPORTER_ASSERT(reporter, as_IB(image)->getTexture() == texture);
}
- surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
- REPORTER_ASSERT(reporter, as_IB(image)->getTexture() == texture);
}
+#endif
+#if SK_SUPPORT_GPU
#include "GrGpuResourcePriv.h"
#include "SkGpuDevice.h"
#include "SkImage_Gpu.h"
#include "SkSurface_Gpu.h"
-SkSurface::Budgeted is_budgeted(SkSurface* surf) {
+static SkSurface::Budgeted is_budgeted(SkSurface* surf) {
return ((SkSurface_Gpu*)surf)->getDevice()->accessRenderTarget()->resourcePriv().isBudgeted() ?
SkSurface::kYes_Budgeted : SkSurface::kNo_Budgeted;
}
-SkSurface::Budgeted is_budgeted(SkImage* image) {
+static SkSurface::Budgeted is_budgeted(SkImage* image) {
return ((SkImage_Gpu*)image)->getTexture()->resourcePriv().isBudgeted() ?
SkSurface::kYes_Budgeted : SkSurface::kNo_Budgeted;
}
-static void test_surface_budget(skiatest::Reporter* reporter, GrContext* context) {
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceBudget, reporter, context) {
SkImageInfo info = SkImageInfo::MakeN32Premul(8,8);
for (int i = 0; i < 2; ++i) {
SkSurface::Budgeted sbudgeted = i ? SkSurface::kYes_Budgeted : SkSurface::kNo_Budgeted;
@@ -525,86 +610,55 @@ static void test_surface_budget(skiatest::Reporter* reporter, GrContext* context
}
}
}
-
#endif
-static void TestSurfaceNoCanvas(skiatest::Reporter* reporter,
- SurfaceType surfaceType,
- GrContext* context,
- SkSurface::ContentChangeMode mode) {
+static void test_no_canvas1(skiatest::Reporter* reporter,
+ SkSurface* surface,
+ SkSurface::ContentChangeMode mode) {
+ // Test passes by not asserting
+ surface->notifyContentWillChange(mode);
+ SkDEBUGCODE(surface->validate();)
+}
+static void test_no_canvas2(skiatest::Reporter* reporter,
+ SkSurface* surface,
+ SkSurface::ContentChangeMode mode) {
// Verifies the robustness of SkSurface for handling use cases where calls
// are made before a canvas is created.
- {
- // Test passes by not asserting
- SkSurface* surface = create_surface(surfaceType, context);
- SkAutoTUnref<SkSurface> aur_surface(surface);
- surface->notifyContentWillChange(mode);
- SkDEBUGCODE(surface->validate();)
- }
- {
- SkSurface* surface = create_surface(surfaceType, context);
- SkAutoTUnref<SkSurface> aur_surface(surface);
- SkImage* image1 = surface->newImageSnapshot();
- SkAutoTUnref<SkImage> aur_image1(image1);
- SkDEBUGCODE(image1->validate();)
- SkDEBUGCODE(surface->validate();)
- surface->notifyContentWillChange(mode);
- SkDEBUGCODE(image1->validate();)
- SkDEBUGCODE(surface->validate();)
- SkImage* image2 = surface->newImageSnapshot();
- SkAutoTUnref<SkImage> aur_image2(image2);
- SkDEBUGCODE(image2->validate();)
- SkDEBUGCODE(surface->validate();)
- REPORTER_ASSERT(reporter, image1 != image2);
+ SkImage* image1 = surface->newImageSnapshot();
+ SkAutoTUnref<SkImage> aur_image1(image1);
+ SkDEBUGCODE(image1->validate();)
+ SkDEBUGCODE(surface->validate();)
+ surface->notifyContentWillChange(mode);
+ SkDEBUGCODE(image1->validate();)
+ SkDEBUGCODE(surface->validate();)
+ SkImage* image2 = surface->newImageSnapshot();
+ SkAutoTUnref<SkImage> aur_image2(image2);
+ SkDEBUGCODE(image2->validate();)
+ SkDEBUGCODE(surface->validate();)
+ REPORTER_ASSERT(reporter, image1 != image2);
+}
+DEF_TEST(SurfaceNoCanvas, reporter) {
+ SkSurface::ContentChangeMode modes[] =
+ { SkSurface::kDiscard_ContentChangeMode, SkSurface::kRetain_ContentChangeMode};
+ for (auto& test_func : { &test_no_canvas1, &test_no_canvas2 }) {
+ for (auto& mode : modes) {
+ SkAutoTUnref<SkSurface> surface(create_surface());
+ test_func(reporter, surface, mode);
+ }
}
-
}
-
-DEF_GPUTEST(Surface, reporter, factory) {
- TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, nullptr);
- TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, nullptr);
- TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kDiscard_ContentChangeMode);
- TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, nullptr, SkSurface::kRetain_ContentChangeMode);
-
-
- test_empty_surface(reporter, nullptr);
-
-
- test_canvaspeek(reporter, factory);
-
- test_accessPixels(reporter, factory);
-
- test_snap_alphatype(reporter, factory);
-
#if SK_SUPPORT_GPU
- TestGetTexture(reporter, kRaster_SurfaceType, nullptr);
- if (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 (context) {
- Test_crbug263329(reporter, kGpu_SurfaceType, context);
- Test_crbug263329(reporter, kGpuScratch_SurfaceType, context);
- TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context);
- TestSurfaceCopyOnWrite(reporter, kGpuScratch_SurfaceType, context);
- TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType, context);
- TestSurfaceWritableAfterSnapshotRelease(reporter, kGpuScratch_SurfaceType, context);
- TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
- TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kDiscard_ContentChangeMode);
- TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
- TestSurfaceNoCanvas(reporter, kGpuScratch_SurfaceType, context, SkSurface::kRetain_ContentChangeMode);
- TestGetTexture(reporter, kGpu_SurfaceType, context);
- TestGetTexture(reporter, kGpuScratch_SurfaceType, context);
- test_empty_surface(reporter, context);
- test_surface_budget(reporter, context);
- test_wrapped_texture_surface(reporter, context);
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceNoCanvas_Gpu, reporter, context) {
+ SkSurface::ContentChangeMode modes[] =
+ { SkSurface::kDiscard_ContentChangeMode, SkSurface::kRetain_ContentChangeMode};
+ for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
+ for (auto& test_func : { &test_no_canvas1, &test_no_canvas2 }) {
+ for (auto& mode : modes) {
+ SkAutoTUnref<SkSurface> surface(
+ surface_func(context, kPremul_SkAlphaType, nullptr));
+ test_func(reporter, surface, mode);
}
}
}
-#endif
}
-
-
+#endif
diff --git a/tests/Test.h b/tests/Test.h
index c1e0c528fb..be2ef1f788 100644
--- a/tests/Test.h
+++ b/tests/Test.h
@@ -13,6 +13,8 @@
#include "SkTypes.h"
class GrContextFactory;
+class GrContext;
+class SkGLContext;
namespace skiatest {
@@ -69,6 +71,17 @@ typedef SkTRegistry<Test> TestRegistry;
...
}
*/
+enum GPUTestContexts {
+ kNone_GPUTestContexts = 0,
+ kNull_GPUTestContexts = 1,
+ kNative_GPUTestContexts = 1 << 1,
+ kOther_GPUTestContexts = 1 << 2, // Other than native, used only for below.
+ kAllRendering_GPUTestContexts = kNative_GPUTestContexts | kOther_GPUTestContexts,
+ kAll_GPUTestContexts = kAllRendering_GPUTestContexts | kNull_GPUTestContexts
+};
+template<typename T>
+void RunWithGPUTestContexts(T testFunction, GPUTestContexts contexts, Reporter* reporter,
+ GrContextFactory* factory);
} // namespace skiatest
#define REPORTER_ASSERT(r, cond) \
@@ -96,12 +109,41 @@ typedef SkTRegistry<Test> TestRegistry;
skiatest::Test(#name, false, test_##name)); \
void test_##name(skiatest::Reporter* reporter, GrContextFactory*)
+#define GPUTEST_EXPAND_MSVC(x) x
+#define GPUTEST_APPLY(C, ...) GPUTEST_EXPAND_MSVC(C(__VA_ARGS__))
+#define GPUTEST_SELECT(a1, a2, N, ...) N
+
+#define GPUTEST_CONTEXT_ARGS1(a1) GrContext* a1
+#define GPUTEST_CONTEXT_ARGS2(a1, a2) GrContext* a1, SkGLContext* a2
+#define GPUTEST_CONTEXT_ARGS(...) \
+ GPUTEST_APPLY(GPUTEST_SELECT(__VA_ARGS__, GPUTEST_CONTEXT_ARGS2, GPUTEST_CONTEXT_ARGS1), \
+ __VA_ARGS__)
+
#define DEF_GPUTEST(name, reporter, factory) \
static void test_##name(skiatest::Reporter*, GrContextFactory*); \
skiatest::TestRegistry name##TestRegistry( \
skiatest::Test(#name, true, test_##name)); \
void test_##name(skiatest::Reporter* reporter, GrContextFactory* factory)
+#define DEF_GPUTEST_FOR_CONTEXTS(name, contexts, reporter, ...) \
+ static void test_##name(skiatest::Reporter*, GPUTEST_CONTEXT_ARGS(__VA_ARGS__)); \
+ static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \
+ GrContextFactory* factory) { \
+ skiatest::RunWithGPUTestContexts(test_##name, contexts, reporter, factory); \
+ } \
+ skiatest::TestRegistry name##TestRegistry( \
+ skiatest::Test(#name, true, test_gpu_contexts_##name)); \
+ void test_##name(skiatest::Reporter* reporter, GPUTEST_CONTEXT_ARGS(__VA_ARGS__))
+
+#define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, ...) \
+ DEF_GPUTEST_FOR_CONTEXTS(name, skiatest::kAll_GPUTestContexts, reporter, __VA_ARGS__)
+#define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, ...) \
+ DEF_GPUTEST_FOR_CONTEXTS(name, skiatest::kAllRendering_GPUTestContexts, reporter, __VA_ARGS__)
+#define DEF_GPUTEST_FOR_NULL_CONTEXT(name, reporter, ...) \
+ DEF_GPUTEST_FOR_CONTEXTS(name, skiatest::kNull_GPUTestContexts, reporter, __VA_ARGS__)
+#define DEF_GPUTEST_FOR_NATIVE_CONTEXT(name, reporter, ...) \
+ DEF_GPUTEST_FOR_CONTEXTS(name, skiatest::kNative_GPUTestContexts, reporter, __VA_ARGS__)
+
#define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER) \
do { \
SkDynamicMemoryWStream testStream; \
diff --git a/tests/TestTest.cpp b/tests/TestTest.cpp
new file mode 100644
index 0000000000..2c303a74ce
--- /dev/null
+++ b/tests/TestTest.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Test.h"
+
+#if SK_SUPPORT_GPU
+#include "GrContext.h"
+#include "gl/SkGLContext.h"
+#endif
+
+
+// This is an example of a normal test.
+DEF_TEST(TestNormal, reporter) {
+ REPORTER_ASSERT(reporter, reporter);
+}
+
+// This is an example of a GPU test that uses common GrContextFactory factory to do the test.
+#if SK_SUPPORT_GPU
+DEF_GPUTEST(TestGpuFactory, reporter, factory) {
+ REPORTER_ASSERT(reporter, reporter);
+ REPORTER_ASSERT(reporter, factory);
+}
+#endif
+
+// This is an example of a GPU test that tests a property that should work for all GPU contexts.
+// Note: Some of the contexts might not produce a rendering output.
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_ALL_CONTEXTS(TestGpuAllContexts, reporter, context) {
+ REPORTER_ASSERT(reporter, reporter);
+ REPORTER_ASSERT(reporter, context);
+}
+#endif
+
+// This is an example of a GPU test that tests a property that should work for all GPU contexts that
+// produce a rendering output.
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TestGpuRenderingContexts, reporter, context) {
+ REPORTER_ASSERT(reporter, reporter);
+ REPORTER_ASSERT(reporter, context);
+}
+#endif
+
+// This is an example of a GPU test that tests a property that should work at least for the native
+// GPU context. If the test takes a long time to run, it may be appropriate to test only the native
+// context.
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(TestGpuNativeContext, reporter, context) {
+ REPORTER_ASSERT(reporter, reporter);
+ REPORTER_ASSERT(reporter, context);
+}
+#endif
+
+// This is an example of a GPU test that tests a property that uses the null GPU context. It should
+// be used if the test tests some behavior that is mocked with the null context.
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_NULL_CONTEXT(TestGpuNullContext, reporter, context) {
+ REPORTER_ASSERT(reporter, reporter);
+ REPORTER_ASSERT(reporter, context);
+}
+#endif
+
+// This is an example of a GPU test that tests a property that should work for all GPU contexts.
+// It uses the additional SkGLContext* glContext to implement the test.
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_ALL_CONTEXTS(TestGpuGrContextAndGLContext, reporter, context, glContext) {
+ REPORTER_ASSERT(reporter, reporter);
+ REPORTER_ASSERT(reporter, context);
+ REPORTER_ASSERT(reporter, glContext);
+}
+#endif
+