Make GM render to render targets that are also textures.

Review URL: https://codereview.chromium.org/13211002

git-svn-id: http://skia.googlecode.com/svn/trunk@8438 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2013-03-28 19:18:12 +00:00
parent ce89a19dd6
commit 123ac1d4ea
3 changed files with 50 additions and 40 deletions

View File

@ -50,7 +50,6 @@
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
#include "GrContextFactory.h" #include "GrContextFactory.h"
#include "GrRenderTarget.h"
#include "SkGpuDevice.h" #include "SkGpuDevice.h"
typedef GrContextFactory::GLContextType GLContextType; typedef GrContextFactory::GLContextType GLContextType;
#define DEFAULT_CACHE_VALUE -1 #define DEFAULT_CACHE_VALUE -1
@ -59,7 +58,7 @@ static int gGpuCacheSizeCount;
#else #else
class GrContextFactory; class GrContextFactory;
class GrContext; class GrContext;
class GrRenderTarget; class GrSurface;
typedef int GLContextType; typedef int GLContextType;
#endif #endif
@ -373,8 +372,7 @@ public:
} }
static ErrorCombination generate_image(GM* gm, const ConfigData& gRec, static ErrorCombination generate_image(GM* gm, const ConfigData& gRec,
GrContext* context, GrSurface* gpuTarget,
GrRenderTarget* rt,
SkBitmap* bitmap, SkBitmap* bitmap,
bool deferred) { bool deferred) {
SkISize size (gm->getISize()); SkISize size (gm->getISize());
@ -394,10 +392,7 @@ public:
} }
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
else { // GPU else { // GPU
if (NULL == context) { SkAutoTUnref<SkDevice> device(SkGpuDevice::Create(gpuTarget));
return ErrorCombination(kNoGpuContext_ErrorType);
}
SkAutoTUnref<SkDevice> device(new SkGpuDevice(context, rt));
if (deferred) { if (deferred) {
canvas.reset(new SkDeferredCanvas(device)); canvas.reset(new SkDeferredCanvas(device));
} else { } else {
@ -826,15 +821,14 @@ public:
ErrorCombination test_drawing(GM* gm, ErrorCombination test_drawing(GM* gm,
const ConfigData& gRec, const ConfigData& gRec,
const char writePath [], const char writePath [],
GrContext* context, GrSurface* gpuTarget,
GrRenderTarget* rt,
SkBitmap* bitmap) { SkBitmap* bitmap) {
SkDynamicMemoryWStream document; SkDynamicMemoryWStream document;
if (gRec.fBackend == kRaster_Backend || if (gRec.fBackend == kRaster_Backend ||
gRec.fBackend == kGPU_Backend) { gRec.fBackend == kGPU_Backend) {
// Early exit if we can't generate the image. // Early exit if we can't generate the image.
ErrorCombination errors = generate_image(gm, gRec, context, rt, bitmap, false); ErrorCombination errors = generate_image(gm, gRec, gpuTarget, bitmap, false);
if (!errors.isEmpty()) { if (!errors.isEmpty()) {
// TODO: Add a test to exercise what the stdout and // TODO: Add a test to exercise what the stdout and
// JSON look like if we get an "early error" while // JSON look like if we get an "early error" while
@ -858,8 +852,7 @@ public:
ErrorCombination test_deferred_drawing(GM* gm, ErrorCombination test_deferred_drawing(GM* gm,
const ConfigData& gRec, const ConfigData& gRec,
const SkBitmap& referenceBitmap, const SkBitmap& referenceBitmap,
GrContext* context, GrSurface* gpuTarget) {
GrRenderTarget* rt) {
SkDynamicMemoryWStream document; SkDynamicMemoryWStream document;
if (gRec.fBackend == kRaster_Backend || if (gRec.fBackend == kRaster_Backend ||
@ -867,7 +860,7 @@ public:
SkBitmap bitmap; SkBitmap bitmap;
// Early exit if we can't generate the image, but this is // Early exit if we can't generate the image, but this is
// expected in some cases, so don't report a test failure. // expected in some cases, so don't report a test failure.
ErrorCombination errors = generate_image(gm, gRec, context, rt, &bitmap, true); ErrorCombination errors = generate_image(gm, gRec, gpuTarget, &bitmap, true);
// TODO(epoger): This logic is the opposite of what is // TODO(epoger): This logic is the opposite of what is
// described above... if we succeeded in generating the // described above... if we succeeded in generating the
// -deferred image, we exit early! We should fix this // -deferred image, we exit early! We should fix this
@ -1183,9 +1176,9 @@ ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si
// Now we know that we want to run this test and record its // Now we know that we want to run this test and record its
// success or failure. // success or failure.
ErrorCombination errorsForThisConfig; ErrorCombination errorsForThisConfig;
GrRenderTarget* renderTarget = NULL; GrSurface* gpuTarget = NULL;
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
SkAutoTUnref<GrRenderTarget> rt; SkAutoTUnref<GrSurface> auGpuTarget;
AutoResetGr autogr; AutoResetGr autogr;
if ((errorsForThisConfig.isEmpty()) && (kGPU_Backend == config.fBackend)) { if ((errorsForThisConfig.isEmpty()) && (kGPU_Backend == config.fBackend)) {
GrContext* gr = grFactory->get(config.fGLContextType); GrContext* gr = grFactory->get(config.fGLContextType);
@ -1198,15 +1191,11 @@ ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si
desc.fWidth = gm->getISize().width(); desc.fWidth = gm->getISize().width();
desc.fHeight = gm->getISize().height(); desc.fHeight = gm->getISize().height();
desc.fSampleCnt = config.fSampleCnt; desc.fSampleCnt = config.fSampleCnt;
GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); auGpuTarget.reset(gr->createUncachedTexture(desc, NULL, 0));
if (tex) { if (NULL != auGpuTarget) {
rt.reset(tex->asRenderTarget()); gpuTarget = auGpuTarget;
rt.get()->ref(); grSuccess = true;
tex->unref();
autogr.set(gr); autogr.set(gr);
renderTarget = rt.get();
grSuccess = NULL != renderTarget;
}
// Set the user specified cache limits if non-default. // Set the user specified cache limits if non-default.
size_t bytes; size_t bytes;
int count; int count;
@ -1219,6 +1208,7 @@ ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si
} }
gr->setTextureCacheLimits(count, bytes); gr->setTextureCacheLimits(count, bytes);
} }
}
if (!grSuccess) { if (!grSuccess) {
errorsForThisConfig.add(kNoGpuContext_ErrorType); errorsForThisConfig.add(kNoGpuContext_ErrorType);
} }
@ -1234,14 +1224,14 @@ ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si
writePath = NULL; writePath = NULL;
} }
if (errorsForThisConfig.isEmpty()) { if (errorsForThisConfig.isEmpty()) {
errorsForThisConfig.add(gmmain.test_drawing(gm, config, writePath, GetGr(), errorsForThisConfig.add(gmmain.test_drawing(gm,config, writePath, gpuTarget,
renderTarget, &comparisonBitmap)); &comparisonBitmap));
} }
if (FLAGS_deferred && errorsForThisConfig.isEmpty() && if (FLAGS_deferred && errorsForThisConfig.isEmpty() &&
(kGPU_Backend == config.fBackend || kRaster_Backend == config.fBackend)) { (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBackend)) {
errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, comparisonBitmap, errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, comparisonBitmap,
GetGr(), renderTarget)); gpuTarget));
} }
errorsForAllConfigs.add(errorsForThisConfig); errorsForAllConfigs.add(errorsForThisConfig);
@ -1595,8 +1585,7 @@ int tool_main(int argc, char** argv) {
SkBitmap comparisonBitmap; SkBitmap comparisonBitmap;
const ConfigData compareConfig = const ConfigData compareConfig =
{ SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "comparison", false }; { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "comparison", false };
testErrors.add(gmmain.generate_image( testErrors.add(gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false));
gm, compareConfig, NULL, NULL, &comparisonBitmap, false));
// TODO(epoger): only run this if gmmain.generate_image() succeeded? // TODO(epoger): only run this if gmmain.generate_image() succeeded?
// Otherwise, what are we comparing against? // Otherwise, what are we comparing against?

View File

@ -27,16 +27,24 @@ class GrTextContext;
*/ */
class SK_API SkGpuDevice : public SkDevice { class SK_API SkGpuDevice : public SkDevice {
public: public:
/**
* Creates an SkGpuDevice from a GrSurface. This will fail if the surface is not a render
* target. The caller owns a ref on the returned device.
*/
static SkGpuDevice* Create(GrSurface* surface);
/** /**
* New device that will create an offscreen renderTarget based on the * New device that will create an offscreen renderTarget based on the
* config, width, height, and sampleCount. The device's storage will not * config, width, height, and sampleCount. The device's storage will not
* count against the GrContext's texture cache budget. The device's pixels * count against the GrContext's texture cache budget. The device's pixels
* will be uninitialized. * will be uninitialized. TODO: This can fail, replace with a factory function.
*/ */
SkGpuDevice(GrContext*, SkBitmap::Config, int width, int height, int sampleCount = 0); SkGpuDevice(GrContext*, SkBitmap::Config, int width, int height, int sampleCount = 0);
/** /**
* New device that will render to the specified renderTarget. * New device that will render to the specified renderTarget.
* DEPRECATED: Use Create(surface)
*/ */
SkGpuDevice(GrContext*, GrRenderTarget*); SkGpuDevice(GrContext*, GrRenderTarget*);
@ -44,6 +52,7 @@ public:
* New device that will render to the texture (as a rendertarget). * New device that will render to the texture (as a rendertarget).
* The GrTexture's asRenderTarget() must be non-NULL or device will not * The GrTexture's asRenderTarget() must be non-NULL or device will not
* function. * function.
* DEPRECATED: Use Create(surface)
*/ */
SkGpuDevice(GrContext*, GrTexture*); SkGpuDevice(GrContext*, GrTexture*);

View File

@ -167,6 +167,18 @@ static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) {
return bitmap; return bitmap;
} }
SkGpuDevice* SkGpuDevice::Create(GrSurface* surface) {
GrAssert(NULL != surface);
if (NULL == surface->asRenderTarget() || NULL == surface->getContext()) {
return NULL;
}
if (surface->asTexture()) {
return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asTexture()));
} else {
return SkNEW_ARGS(SkGpuDevice, (surface->getContext(), surface->asRenderTarget()));
}
}
SkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture) SkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture)
: SkDevice(make_bitmap(context, texture->asRenderTarget())) { : SkDevice(make_bitmap(context, texture->asRenderTarget())) {
this->initFromRenderTarget(context, texture->asRenderTarget(), false); this->initFromRenderTarget(context, texture->asRenderTarget(), false);