Revert of Make NVPR a GL context option instead of a GL context (patchset #2 id:20001 of https://codereview.chromium.org/1448883002/ )
Reason for revert: BUG=skia:4609 skbug.com/4609 Seems like GrContextFactory needs to fail when the NVPR option is requested but the driver version isn't sufficiently high. Original issue's description: > Make NVPR a GL context option instead of a GL context > > Make NVPR a GL context option instead of a GL context. > This may enable NVPR to be run with command buffer > interface. > > No functionality change in DM or nanobench. NVPR can > only be run with normal GL APIs. > > BUG=skia:2992 > > Committed: https://skia.googlesource.com/skia/+/eeebdb538d476c1bfc8b63a946094ca1b505ecd1 TBR=mtklein@google.com,jvanverth@google.com,kkinnunen@nvidia.com NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia:2992 Review URL: https://codereview.chromium.org/1486153002
This commit is contained in:
parent
cb6cb21cd9
commit
a0a024e323
@ -169,13 +169,10 @@ struct GPUTarget : public Target {
|
||||
uint32_t flags = this->config.useDFText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag :
|
||||
0;
|
||||
SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->config.ctxType,
|
||||
kNone_GrGLStandard,
|
||||
this->config.ctxOptions),
|
||||
this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->config.ctxType),
|
||||
SkSurface::kNo_Budgeted, info,
|
||||
this->config.samples, &props));
|
||||
this->gl = gGrFactory->getContextInfo(this->config.ctxType, kNone_GrGLStandard,
|
||||
this->config.ctxOptions)->fGLContext;
|
||||
this->gl = gGrFactory->getContextInfo(this->config.ctxType)->fGLContext;
|
||||
if (!this->surface.get()) {
|
||||
return false;
|
||||
}
|
||||
@ -387,12 +384,11 @@ static bool is_cpu_config_allowed(const char* name) {
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
static bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextType ctxType,
|
||||
GrContextFactory::GLContextOptions ctxOptions,
|
||||
int sampleCnt) {
|
||||
if (!is_cpu_config_allowed(name)) {
|
||||
return false;
|
||||
}
|
||||
if (const GrContext* ctx = gGrFactory->get(ctxType, kNone_GrGLStandard, ctxOptions)) {
|
||||
if (const GrContext* ctx = gGrFactory->get(ctxType)) {
|
||||
return sampleCnt <= ctx->caps()->maxSampleCount();
|
||||
}
|
||||
return false;
|
||||
@ -401,20 +397,17 @@ static bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextT
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#define kBogusGLContextType GrContextFactory::kNative_GLContextType
|
||||
#define kBogusGLContextOptions GrContextFactory::kNone_GLContextOptions
|
||||
#else
|
||||
#define kBogusGLContextType 0
|
||||
#define kBogusGLContextOptions 0
|
||||
#endif
|
||||
|
||||
// Append all configs that are enabled and supported.
|
||||
static void create_configs(SkTDArray<Config>* configs) {
|
||||
#define CPU_CONFIG(name, backend, color, alpha) \
|
||||
if (is_cpu_config_allowed(#name)) { \
|
||||
Config config = { #name, Benchmark::backend, color, alpha, 0, \
|
||||
kBogusGLContextType, kBogusGLContextOptions, \
|
||||
false }; \
|
||||
configs->push(config); \
|
||||
#define CPU_CONFIG(name, backend, color, alpha) \
|
||||
if (is_cpu_config_allowed(#name)) { \
|
||||
Config config = { #name, Benchmark::backend, color, alpha, 0, \
|
||||
kBogusGLContextType, false }; \
|
||||
configs->push(config); \
|
||||
}
|
||||
|
||||
if (FLAGS_cpu) {
|
||||
@ -424,9 +417,8 @@ static void create_configs(SkTDArray<Config>* configs) {
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#define GPU_CONFIG(name, ctxType, ctxOptions, samples, useDFText) \
|
||||
if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, \
|
||||
GrContextFactory::ctxOptions, samples)) { \
|
||||
#define GPU_CONFIG(name, ctxType, samples, useDFText) \
|
||||
if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) { \
|
||||
Config config = { \
|
||||
#name, \
|
||||
Benchmark::kGPU_Backend, \
|
||||
@ -434,29 +426,28 @@ static void create_configs(SkTDArray<Config>* configs) {
|
||||
kPremul_SkAlphaType, \
|
||||
samples, \
|
||||
GrContextFactory::ctxType, \
|
||||
GrContextFactory::ctxOptions, \
|
||||
useDFText }; \
|
||||
configs->push(config); \
|
||||
}
|
||||
|
||||
if (FLAGS_gpu) {
|
||||
GPU_CONFIG(gpu, kNative_GLContextType, kNone_GLContextOptions, 0, false)
|
||||
GPU_CONFIG(msaa4, kNative_GLContextType, kNone_GLContextOptions, 4, false)
|
||||
GPU_CONFIG(msaa16, kNative_GLContextType, kNone_GLContextOptions, 16, false)
|
||||
GPU_CONFIG(nvprmsaa4, kNative_GLContextType, kEnableNVPR_GLContextOptions, 4, false)
|
||||
GPU_CONFIG(nvprmsaa16, kNative_GLContextType, kEnableNVPR_GLContextOptions, 16, false)
|
||||
GPU_CONFIG(gpudft, kNative_GLContextType, kNone_GLContextOptions, 0, true)
|
||||
GPU_CONFIG(debug, kDebug_GLContextType, kNone_GLContextOptions, 0, false)
|
||||
GPU_CONFIG(nullgpu, kNull_GLContextType, kNone_GLContextOptions, 0, false)
|
||||
GPU_CONFIG(gpu, kNative_GLContextType, 0, false)
|
||||
GPU_CONFIG(msaa4, kNative_GLContextType, 4, false)
|
||||
GPU_CONFIG(msaa16, kNative_GLContextType, 16, false)
|
||||
GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4, false)
|
||||
GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16, false)
|
||||
GPU_CONFIG(gpudft, kNative_GLContextType, 0, true)
|
||||
GPU_CONFIG(debug, kDebug_GLContextType, 0, false)
|
||||
GPU_CONFIG(nullgpu, kNull_GLContextType, 0, false)
|
||||
#ifdef SK_ANGLE
|
||||
GPU_CONFIG(angle, kANGLE_GLContextType, kNone_GLContextOptions, 0, false)
|
||||
GPU_CONFIG(angle-gl, kANGLE_GL_GLContextType, kNone_GLContextOptions, 0, false)
|
||||
GPU_CONFIG(angle, kANGLE_GLContextType, 0, false)
|
||||
GPU_CONFIG(angle-gl, kANGLE_GL_GLContextType, 0, false)
|
||||
#endif
|
||||
#ifdef SK_COMMAND_BUFFER
|
||||
GPU_CONFIG(commandbuffer, kCommandBuffer_GLContextType, kNone_GLContextOptions, 0, false)
|
||||
GPU_CONFIG(commandbuffer, kCommandBuffer_GLContextType, 0, false)
|
||||
#endif
|
||||
#if SK_MESA
|
||||
GPU_CONFIG(mesa, kMESA_GLContextType, kNone_GLContextOptions, 0, false)
|
||||
GPU_CONFIG(mesa, kMESA_GLContextType, 0, false)
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@ -1253,10 +1244,8 @@ int nanobench_main() {
|
||||
#if SK_SUPPORT_GPU
|
||||
if (FLAGS_gpuStats &&
|
||||
Benchmark::kGPU_Backend == configs[i].backend) {
|
||||
GrContext* context = gGrFactory->get(configs[i].ctxType,
|
||||
kNone_GrGLStandard, configs[i].ctxOptions);
|
||||
context->printCacheStats();
|
||||
context->printGpuStats();
|
||||
gGrFactory->get(configs[i].ctxType)->printCacheStats();
|
||||
gGrFactory->get(configs[i].ctxType)->printGpuStats();
|
||||
}
|
||||
#endif
|
||||
if (FLAGS_verbose) {
|
||||
|
@ -29,11 +29,9 @@ struct Config {
|
||||
int samples;
|
||||
#if SK_SUPPORT_GPU
|
||||
GrContextFactory::GLContextType ctxType;
|
||||
GrContextFactory::GLContextOptions ctxOptions;
|
||||
bool useDFText;
|
||||
#else
|
||||
int bogusInt;
|
||||
int bogusIntOption;
|
||||
bool bogusBool;
|
||||
#endif
|
||||
};
|
||||
|
12
dm/DM.cpp
12
dm/DM.cpp
@ -609,8 +609,8 @@ static Sink* create_sink(const char* tag) {
|
||||
SINK("gpudft", GPUSink, Gr::kNative_GLContextType, api, 0, true, FLAGS_gpu_threading);
|
||||
SINK("msaa4", GPUSink, Gr::kNative_GLContextType, api, 4, false, FLAGS_gpu_threading);
|
||||
SINK("msaa16", GPUSink, Gr::kNative_GLContextType, api, 16, false, FLAGS_gpu_threading);
|
||||
SINK("nvprmsaa4", GPUSink, Gr::kNative_GLContextType, Gr::kEnableNVPR_GLContextOptions, api, 4, true, FLAGS_gpu_threading);
|
||||
SINK("nvprmsaa16", GPUSink, Gr::kNative_GLContextType, Gr::kEnableNVPR_GLContextOptions, api, 16, true, FLAGS_gpu_threading);
|
||||
SINK("nvprmsaa4", GPUSink, Gr::kNVPR_GLContextType, api, 4, true, FLAGS_gpu_threading);
|
||||
SINK("nvprmsaa16", GPUSink, Gr::kNVPR_GLContextType, api, 16, true, FLAGS_gpu_threading);
|
||||
#if SK_ANGLE
|
||||
SINK("angle", GPUSink, Gr::kANGLE_GLContextType, api, 0, false, FLAGS_gpu_threading);
|
||||
SINK("angle-gl", GPUSink, Gr::kANGLE_GL_GLContextType, api, 0, false, FLAGS_gpu_threading);
|
||||
@ -1171,7 +1171,6 @@ template<typename T>
|
||||
void RunWithGPUTestContexts(T test, GPUTestContexts testContexts, Reporter* reporter,
|
||||
GrContextFactory* factory) {
|
||||
#if SK_SUPPORT_GPU
|
||||
const GrGLStandard api = get_gpu_api();
|
||||
for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
|
||||
GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
|
||||
int contextSelector = kNone_GPUTestContexts;
|
||||
@ -1187,12 +1186,7 @@ void RunWithGPUTestContexts(T test, GPUTestContexts testContexts, Reporter* repo
|
||||
if ((testContexts & contextSelector) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (GrContextFactory::ContextInfo* context = factory->getContextInfo(glCtxType, api)) {
|
||||
call_test(test, reporter, context);
|
||||
}
|
||||
if (GrContextFactory::ContextInfo* context =
|
||||
factory->getContextInfo(glCtxType, api,
|
||||
GrContextFactory::kEnableNVPR_GLContextOptions)) {
|
||||
if (GrContextFactory::ContextInfo* context = factory->getContextInfo(glCtxType)) {
|
||||
call_test(test, reporter, context);
|
||||
}
|
||||
}
|
||||
|
@ -26,14 +26,13 @@ static const bool kGPUDisabled = false;
|
||||
|
||||
static inline SkSurface* NewGpuSurface(GrContextFactory* grFactory,
|
||||
GrContextFactory::GLContextType type,
|
||||
GrContextFactory::GLContextOptions options,
|
||||
GrGLStandard gpuAPI,
|
||||
SkImageInfo info,
|
||||
int samples,
|
||||
bool useDIText) {
|
||||
uint32_t flags = useDIText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 0;
|
||||
SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
|
||||
return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI, options), SkSurface::kNo_Budgeted,
|
||||
return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI), SkSurface::kNo_Budgeted,
|
||||
info, samples, &props);
|
||||
}
|
||||
|
||||
@ -77,10 +76,6 @@ public:
|
||||
kNative_GLContextType = 0,
|
||||
kNull_GLContextType = 0;
|
||||
static const int kGLContextTypeCnt = 1;
|
||||
enum GLContextOptions {
|
||||
kNone_GLContextOptions = 0,
|
||||
kEnableNVPR_GLContextOptions = 0x1,
|
||||
};
|
||||
void destroyContexts() {}
|
||||
|
||||
void abandonContexts() {}
|
||||
@ -92,7 +87,6 @@ static const bool kGPUDisabled = true;
|
||||
|
||||
static inline SkSurface* NewGpuSurface(GrContextFactory*,
|
||||
GrContextFactory::GLContextType,
|
||||
GrContextFactory::GLContextOptions,
|
||||
GrGLStandard,
|
||||
SkImageInfo,
|
||||
int,
|
||||
|
@ -789,26 +789,12 @@ Error NullSink::draw(const Src& src, SkBitmap*, SkWStream*, SkString*) const {
|
||||
DEFINE_bool(gpuStats, false, "Append GPU stats to the log for each GPU task?");
|
||||
|
||||
GPUSink::GPUSink(GrContextFactory::GLContextType ct,
|
||||
GrGLStandard gpuAPI,
|
||||
GrGLStandard api,
|
||||
int samples,
|
||||
bool diText,
|
||||
bool threaded)
|
||||
: fContextType(ct)
|
||||
, fContextOptions(GrContextFactory::kNone_GLContextOptions)
|
||||
, fGpuAPI(gpuAPI)
|
||||
, fSampleCount(samples)
|
||||
, fUseDIText(diText)
|
||||
, fThreaded(threaded) {}
|
||||
|
||||
GPUSink::GPUSink(GrContextFactory::GLContextType ct,
|
||||
GrContextFactory::GLContextOptions options,
|
||||
GrGLStandard gpuAPI,
|
||||
int samples,
|
||||
bool diText,
|
||||
bool threaded)
|
||||
: fContextType(ct)
|
||||
, fContextOptions(options)
|
||||
, fGpuAPI(gpuAPI)
|
||||
, fGpuAPI(api)
|
||||
, fSampleCount(samples)
|
||||
, fUseDIText(diText)
|
||||
, fThreaded(threaded) {}
|
||||
@ -823,21 +809,21 @@ DEFINE_bool(imm, false, "Run gpu configs in immediate mode.");
|
||||
DEFINE_bool(batchClip, false, "Clip each GrBatch to its device bounds for testing.");
|
||||
|
||||
Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) const {
|
||||
GrContextOptions grOptions;
|
||||
GrContextOptions options;
|
||||
if (FLAGS_imm) {
|
||||
grOptions.fImmediateMode = true;
|
||||
options.fImmediateMode = true;
|
||||
}
|
||||
if (FLAGS_batchClip) {
|
||||
grOptions.fClipBatchToBounds = true;
|
||||
options.fClipBatchToBounds = true;
|
||||
}
|
||||
src.modifyGrContextOptions(&grOptions);
|
||||
src.modifyGrContextOptions(&options);
|
||||
|
||||
GrContextFactory factory(grOptions);
|
||||
GrContextFactory factory(options);
|
||||
const SkISize size = src.size();
|
||||
const SkImageInfo info =
|
||||
SkImageInfo::Make(size.width(), size.height(), kN32_SkColorType, kPremul_SkAlphaType);
|
||||
SkAutoTUnref<SkSurface> surface(
|
||||
NewGpuSurface(&factory, fContextType, fContextOptions, fGpuAPI, info, fSampleCount, fUseDIText));
|
||||
NewGpuSurface(&factory, fContextType, fGpuAPI, info, fSampleCount, fUseDIText));
|
||||
if (!surface) {
|
||||
return "Could not create a surface.";
|
||||
}
|
||||
|
@ -214,22 +214,18 @@ public:
|
||||
|
||||
class GPUSink : public Sink {
|
||||
public:
|
||||
GPUSink(GrContextFactory::GLContextType, GrGLStandard, int samples,
|
||||
bool diText, bool threaded);
|
||||
GPUSink(GrContextFactory::GLContextType, GrContextFactory::GLContextOptions,
|
||||
GrGLStandard, int samples, bool diText, bool threaded);
|
||||
GPUSink(GrContextFactory::GLContextType, GrGLStandard, int samples, bool diText, bool threaded);
|
||||
|
||||
Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
|
||||
int enclave() const override;
|
||||
const char* fileExtension() const override { return "png"; }
|
||||
SinkFlags flags() const override { return SinkFlags{ SinkFlags::kGPU, SinkFlags::kDirect }; }
|
||||
private:
|
||||
GrContextFactory::GLContextType fContextType;
|
||||
GrContextFactory::GLContextOptions fContextOptions;
|
||||
GrGLStandard fGpuAPI;
|
||||
int fSampleCount;
|
||||
bool fUseDIText;
|
||||
bool fThreaded;
|
||||
GrContextFactory::GLContextType fContextType;
|
||||
GrGLStandard fGpuAPI;
|
||||
int fSampleCount;
|
||||
bool fUseDIText;
|
||||
bool fThreaded;
|
||||
};
|
||||
|
||||
class PDFSink : public Sink {
|
||||
|
@ -24,21 +24,21 @@
|
||||
#include "GrCaps.h"
|
||||
|
||||
GrContextFactory::ContextInfo* GrContextFactory::getContextInfo(GLContextType type,
|
||||
GrGLStandard forcedGpuAPI,
|
||||
GLContextOptions options) {
|
||||
GrGLStandard forcedGpuAPI) {
|
||||
for (int i = 0; i < fContexts.count(); ++i) {
|
||||
if (fContexts[i]->fType == type &&
|
||||
fContexts[i]->fOptions == options &&
|
||||
(forcedGpuAPI == kNone_GrGLStandard ||
|
||||
forcedGpuAPI == fContexts[i]->fGLContext->gl()->fStandard)) {
|
||||
if (forcedGpuAPI != kNone_GrGLStandard &&
|
||||
forcedGpuAPI != fContexts[i]->fGLContext->gl()->fStandard)
|
||||
continue;
|
||||
|
||||
if (fContexts[i]->fType == type) {
|
||||
fContexts[i]->fGLContext->makeCurrent();
|
||||
return fContexts[i];
|
||||
}
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkGLContext> glCtx;
|
||||
SkAutoTUnref<GrContext> grCtx;
|
||||
switch (type) {
|
||||
case kNVPR_GLContextType: // fallthru
|
||||
case kNative_GLContextType:
|
||||
glCtx.reset(SkCreatePlatformGLContext(forcedGpuAPI));
|
||||
break;
|
||||
@ -75,7 +75,7 @@ GrContextFactory::ContextInfo* GrContextFactory::getContextInfo(GLContextType ty
|
||||
|
||||
// Block NVPR from non-NVPR types.
|
||||
SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx->gl()));
|
||||
if (!(kEnableNVPR_GLContextOptions & options)) {
|
||||
if (kNVPR_GLContextType != type) {
|
||||
glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
|
||||
if (!glInterface) {
|
||||
return nullptr;
|
||||
@ -97,7 +97,7 @@ GrContextFactory::ContextInfo* GrContextFactory::getContextInfo(GLContextType ty
|
||||
return nullptr;
|
||||
}
|
||||
// Warn if path rendering support is not available for the NVPR type.
|
||||
if (kEnableNVPR_GLContextOptions & options) {
|
||||
if (kNVPR_GLContextType == type) {
|
||||
if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
|
||||
GrGpu* gpu = grCtx->getGpu();
|
||||
const GrGLContext* ctx = gpu->glContextForTesting();
|
||||
@ -119,6 +119,5 @@ GrContextFactory::ContextInfo* GrContextFactory::getContextInfo(GLContextType ty
|
||||
ctx->fGLContext = SkRef(glCtx.get());
|
||||
ctx->fGrContext = SkRef(grCtx.get());
|
||||
ctx->fType = type;
|
||||
ctx->fOptions = options;
|
||||
return ctx;
|
||||
}
|
||||
|
@ -23,34 +23,35 @@
|
||||
*/
|
||||
class GrContextFactory : SkNoncopyable {
|
||||
public:
|
||||
/**
|
||||
* Types of GL contexts supported. For historical and testing reasons the native GrContext will
|
||||
* not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context
|
||||
* type that does not remove NVPR support and which will fail when the driver does not support
|
||||
* the extension.
|
||||
*/
|
||||
enum GLContextType {
|
||||
kNative_GLContextType,
|
||||
kNative_GLContextType,
|
||||
#if SK_ANGLE
|
||||
kANGLE_GLContextType,
|
||||
kANGLE_GL_GLContextType,
|
||||
kANGLE_GLContextType,
|
||||
kANGLE_GL_GLContextType,
|
||||
#endif
|
||||
#if SK_COMMAND_BUFFER
|
||||
kCommandBuffer_GLContextType,
|
||||
kCommandBuffer_GLContextType,
|
||||
#endif
|
||||
#if SK_MESA
|
||||
kMESA_GLContextType,
|
||||
kMESA_GLContextType,
|
||||
#endif
|
||||
kNull_GLContextType,
|
||||
kDebug_GLContextType,
|
||||
kLastGLContextType = kDebug_GLContextType
|
||||
/** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not
|
||||
support NVPR */
|
||||
kNVPR_GLContextType,
|
||||
kNull_GLContextType,
|
||||
kDebug_GLContextType,
|
||||
|
||||
kLastGLContextType = kDebug_GLContextType
|
||||
};
|
||||
|
||||
static const int kGLContextTypeCnt = kLastGLContextType + 1;
|
||||
|
||||
/**
|
||||
* Options for GL context creation. For historical and testing reasons the options will default
|
||||
* to not using GL_NV_path_rendering extension even when the driver supports it.
|
||||
*/
|
||||
enum GLContextOptions {
|
||||
kNone_GLContextOptions = 0,
|
||||
kEnableNVPR_GLContextOptions = 0x1,
|
||||
};
|
||||
|
||||
static bool IsRenderingGLContext(GLContextType type) {
|
||||
switch (type) {
|
||||
case kNull_GLContextType:
|
||||
@ -81,6 +82,8 @@ public:
|
||||
case kMESA_GLContextType:
|
||||
return "mesa";
|
||||
#endif
|
||||
case kNVPR_GLContextType:
|
||||
return "nvpr";
|
||||
case kDebug_GLContextType:
|
||||
return "debug";
|
||||
default:
|
||||
@ -116,7 +119,6 @@ public:
|
||||
|
||||
struct ContextInfo {
|
||||
GLContextType fType;
|
||||
GLContextOptions fOptions;
|
||||
SkGLContext* fGLContext;
|
||||
GrContext* fGrContext;
|
||||
};
|
||||
@ -124,14 +126,13 @@ public:
|
||||
* Get a context initialized with a type of GL context. It also makes the GL context current.
|
||||
* Pointer is valid until destroyContexts() is called.
|
||||
*/
|
||||
ContextInfo* getContextInfo(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard, GLContextOptions options = kNone_GLContextOptions);
|
||||
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,
|
||||
GLContextOptions options = kNone_GLContextOptions) {
|
||||
if (ContextInfo* info = this->getContextInfo(type, forcedGpuAPI, options)) {
|
||||
GrContext* get(GLContextType type, GrGLStandard forcedGpuAPI = kNone_GrGLStandard) {
|
||||
if (ContextInfo* info = this->getContextInfo(type, forcedGpuAPI)) {
|
||||
return info->fGrContext;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -12,33 +12,28 @@
|
||||
|
||||
#include "GrContextFactory.h"
|
||||
|
||||
DEF_GPUTEST(GLInterfaceValidation, reporter, /*factory*/) {
|
||||
GrContextFactory testFactory;
|
||||
DEF_GPUTEST(GLInterfaceValidation, reporter, factory) {
|
||||
for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) {
|
||||
GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType)i;
|
||||
// this forces the factory to make the context if it hasn't yet
|
||||
GrContextFactory::ContextInfo* contextInfo = factory->getContextInfo(glCtxType);
|
||||
SkGLContext* glCtx = contextInfo ? contextInfo->fGLContext : nullptr;
|
||||
|
||||
// Test that if we do not have NV_path_rendering -related GL extensions,
|
||||
// GrContextFactory::get(.., kEnableNVPR_GLContextOptions) always returns nullptr.
|
||||
for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
|
||||
GrContextFactory::GLContextType glCtxType = static_cast<GrContextFactory::GLContextType>(i);
|
||||
GrContextFactory::ContextInfo* context =
|
||||
testFactory.getContextInfo(glCtxType, kNone_GrGLStandard,
|
||||
GrContextFactory::kNone_GLContextOptions);
|
||||
if (!context) {
|
||||
// We're supposed to fail the NVPR context type when we the native context that does not
|
||||
// support the NVPR extension.
|
||||
if (GrContextFactory::kNVPR_GLContextType == glCtxType &&
|
||||
factory->getContextInfo(GrContextFactory::kNative_GLContextType) &&
|
||||
!factory->getContextInfo(GrContextFactory::kNative_GLContextType)->fGLContext->gl()->hasExtension("GL_NV_path_rendering")) {
|
||||
REPORTER_ASSERT(reporter, nullptr == glCtx);
|
||||
continue;
|
||||
}
|
||||
|
||||
SkGLContext* glContext = context->fGLContext;
|
||||
REPORTER_ASSERT(reporter, glContext->gl()->validate());
|
||||
|
||||
if (!(glContext->gl()->hasExtension("GL_NV_path_rendering") ||
|
||||
glContext->gl()->hasExtension("GL_CHROMIUM_path_rendering"))) {
|
||||
REPORTER_ASSERT(reporter,
|
||||
nullptr == testFactory.getContextInfo(
|
||||
glCtxType,
|
||||
kNone_GrGLStandard,
|
||||
GrContextFactory::kEnableNVPR_GLContextOptions));
|
||||
REPORTER_ASSERT(reporter, glCtx);
|
||||
if (glCtx) {
|
||||
const GrGLInterface* interface = glCtx->gl();
|
||||
REPORTER_ASSERT(reporter, interface->validate());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -10,24 +10,8 @@
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
#include "GrContextFactory.h"
|
||||
#include "GrCaps.h"
|
||||
#include "Test.h"
|
||||
|
||||
DEF_GPUTEST(GrContextFactoryNVPRContextOptions, reporter, /*factory*/) {
|
||||
GrContextFactory testFactory;
|
||||
// Test that if NVPR is possible, caps are in sync.
|
||||
for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
|
||||
GrContextFactory::GLContextType glCtxType = static_cast<GrContextFactory::GLContextType>(i);
|
||||
GrContext* context = testFactory.get(glCtxType,
|
||||
kNone_GrGLStandard,
|
||||
GrContextFactory::kEnableNVPR_GLContextOptions);
|
||||
if (!context) {
|
||||
continue;
|
||||
}
|
||||
REPORTER_ASSERT(
|
||||
reporter,
|
||||
context->caps()->shaderCaps()->pathRenderingSupport());
|
||||
}
|
||||
}
|
||||
// TODO: test GrContextFactory.
|
||||
|
||||
#endif
|
||||
|
@ -1,707 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef PictureRenderer_DEFINED
|
||||
#define PictureRenderer_DEFINED
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDrawFilter.h"
|
||||
#include "SkJSONCPP.h"
|
||||
#include "SkMath.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkPictureRecorder.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContextFactory.h"
|
||||
#include "GrContext.h"
|
||||
#endif
|
||||
|
||||
struct GrContextOptions;
|
||||
class SkBitmap;
|
||||
class SkCanvas;
|
||||
class SkGLContext;
|
||||
class SkThread;
|
||||
|
||||
namespace sk_tools {
|
||||
|
||||
class TiledPictureRenderer;
|
||||
|
||||
class PictureRenderer : public SkRefCnt {
|
||||
|
||||
public:
|
||||
enum SkDeviceTypes {
|
||||
#if SK_ANGLE
|
||||
kAngle_DeviceType,
|
||||
#endif
|
||||
#if SK_COMMAND_BUFFER
|
||||
kCommandBuffer_DeviceType,
|
||||
#endif
|
||||
#if SK_MESA
|
||||
kMesa_DeviceType,
|
||||
#endif
|
||||
kBitmap_DeviceType,
|
||||
#if SK_SUPPORT_GPU
|
||||
kGPU_DeviceType,
|
||||
kNVPR_DeviceType,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum BBoxHierarchyType {
|
||||
kNone_BBoxHierarchyType = 0,
|
||||
kRTree_BBoxHierarchyType,
|
||||
|
||||
kLast_BBoxHierarchyType = kRTree_BBoxHierarchyType,
|
||||
};
|
||||
|
||||
// this uses SkPaint::Flags as a base and adds additional flags
|
||||
enum DrawFilterFlags {
|
||||
kNone_DrawFilterFlag = 0,
|
||||
kHinting_DrawFilterFlag = 0x10000, // toggles between no hinting and normal hinting
|
||||
kSlightHinting_DrawFilterFlag = 0x20000, // toggles between slight and normal hinting
|
||||
kAAClip_DrawFilterFlag = 0x40000, // toggles between soft and hard clip
|
||||
kMaskFilter_DrawFilterFlag = 0x80000, // toggles on/off mask filters (e.g., blurs)
|
||||
};
|
||||
|
||||
static_assert(!(kMaskFilter_DrawFilterFlag & SkPaint::kAllFlags),
|
||||
"maskfilter_flag_must_be_greater");
|
||||
static_assert(!(kHinting_DrawFilterFlag & SkPaint::kAllFlags),
|
||||
"hinting_flag_must_be_greater");
|
||||
static_assert(!(kSlightHinting_DrawFilterFlag & SkPaint::kAllFlags),
|
||||
"slight_hinting_flag_must_be_greater");
|
||||
|
||||
/**
|
||||
* Called with each new SkPicture to render.
|
||||
*
|
||||
* @param pict The SkPicture to render.
|
||||
* @param writePath The output directory within which this renderer should write all images,
|
||||
* or nullptr if this renderer should not write all images.
|
||||
* @param mismatchPath The output directory within which this renderer should write any images
|
||||
* which do not match expectations, or nullptr if this renderer should not write mismatches.
|
||||
* @param inputFilename The name of the input file we are rendering.
|
||||
* @param useChecksumBasedFilenames Whether to use checksum-based filenames when writing
|
||||
* bitmap images to disk.
|
||||
* @param useMultiPictureDraw true if MultiPictureDraw should be used for rendering
|
||||
*/
|
||||
virtual void init(const SkPicture* pict,
|
||||
const SkString* writePath,
|
||||
const SkString* mismatchPath,
|
||||
const SkString* inputFilename,
|
||||
bool useChecksumBasedFilenames,
|
||||
bool useMultiPictureDraw);
|
||||
|
||||
/**
|
||||
* Set the viewport so that only the portion listed gets drawn.
|
||||
*/
|
||||
void setViewport(SkISize size) { fViewport = size; }
|
||||
|
||||
/**
|
||||
* Set the scale factor at which draw the picture.
|
||||
*/
|
||||
void setScaleFactor(SkScalar scale) { fScaleFactor = scale; }
|
||||
|
||||
/**
|
||||
* Perform any setup that should done prior to each iteration of render() which should not be
|
||||
* timed.
|
||||
*/
|
||||
virtual void setup() {}
|
||||
|
||||
/**
|
||||
* Perform the work. If this is being called within the context of bench_pictures,
|
||||
* this is the step that will be timed.
|
||||
*
|
||||
* Typically "the work" is rendering an SkPicture into a bitmap, but in some subclasses
|
||||
* it is recording the source SkPicture into another SkPicture.
|
||||
*
|
||||
* If fWritePath has been specified, the result of the work will be written to that dir.
|
||||
* If fMismatchPath has been specified, and the actual image result differs from its
|
||||
* expectation, the result of the work will be written to that dir.
|
||||
*
|
||||
* @param out If non-null, the implementing subclass MAY allocate an SkBitmap, copy the
|
||||
* output image into it, and return it here. (Some subclasses ignore this parameter)
|
||||
* @return bool True if rendering succeeded and, if fWritePath had been specified, the output
|
||||
* was successfully written to a file.
|
||||
*/
|
||||
virtual bool render(SkBitmap** out = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* Called once finished with a particular SkPicture, before calling init again, and before
|
||||
* being done with this Renderer.
|
||||
*/
|
||||
virtual void end();
|
||||
|
||||
/**
|
||||
* If this PictureRenderer is actually a TiledPictureRender, return a pointer to this as a
|
||||
* TiledPictureRender so its methods can be called.
|
||||
*/
|
||||
virtual TiledPictureRenderer* getTiledRenderer() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Resets the GPU's state. Does nothing if the backing is raster. For a GPU renderer, calls
|
||||
* flush, swapBuffers and, if callFinish is true, finish.
|
||||
* @param callFinish Whether to call finish.
|
||||
*/
|
||||
void resetState(bool callFinish);
|
||||
|
||||
/**
|
||||
* Remove all decoded textures from the CPU caches and all uploaded textures
|
||||
* from the GPU.
|
||||
*/
|
||||
void purgeTextures();
|
||||
|
||||
/**
|
||||
* Set the backend type. Returns true on success and false on failure.
|
||||
*/
|
||||
#if SK_SUPPORT_GPU
|
||||
bool setDeviceType(SkDeviceTypes deviceType, GrGLStandard gpuAPI = kNone_GrGLStandard) {
|
||||
#else
|
||||
bool setDeviceType(SkDeviceTypes deviceType) {
|
||||
#endif
|
||||
fDeviceType = deviceType;
|
||||
#if SK_SUPPORT_GPU
|
||||
// In case this function is called more than once
|
||||
fGrContext.reset();
|
||||
fGLContext.reset();
|
||||
|
||||
// Set to Native so it will have an initial value.
|
||||
GrContextFactory::GLContextType glContextType = GrContextFactory::kNative_GLContextType;
|
||||
GrContextFactory::GLContextType glContextOptions = GrContextFactory::kNone_GLContextOptions;
|
||||
#endif
|
||||
switch(deviceType) {
|
||||
case kBitmap_DeviceType:
|
||||
return true;
|
||||
#if SK_SUPPORT_GPU
|
||||
case kGPU_DeviceType:
|
||||
// Already set to GrContextFactory::kNative_GLContextType, above.
|
||||
break;
|
||||
case kNVPR_DeviceType:
|
||||
// Already set to GrContextFactory::kNative_GLContextType, above.
|
||||
glContextOptions = GrContextFactory::kEnableNVPR_GLContextOptions;
|
||||
break;
|
||||
#if SK_ANGLE
|
||||
case kAngle_DeviceType:
|
||||
glContextType = GrContextFactory::kANGLE_GLContextType;
|
||||
break;
|
||||
#endif
|
||||
#if SK_COMMAND_BUFFER
|
||||
case kCommandBuffer_DeviceType:
|
||||
glContextType = GrContextFactory::kCommandBuffer_GLContextType;
|
||||
break;
|
||||
#endif
|
||||
#if SK_MESA
|
||||
case kMesa_DeviceType:
|
||||
glContextType = GrContextFactory::kMESA_GLContextType;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
// Invalid device type.
|
||||
return false;
|
||||
}
|
||||
#if SK_SUPPORT_GPU
|
||||
GrContextFactory::ContextInfo* contextInfo = fGrContextFactory.getContextInfo(glContextType, gpuAPI, glContextOptions);
|
||||
if (contextInfo) {
|
||||
fGrContext.reset(SkRef(contextInfo->fGrContext));
|
||||
fGLContext.reset(SkRef(contextInfo->fGLContext));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
void setSampleCount(int sampleCount) {
|
||||
fSampleCount = sampleCount;
|
||||
}
|
||||
|
||||
void setUseDFText(bool useDFText) {
|
||||
fUseDFText = useDFText;
|
||||
}
|
||||
#endif
|
||||
|
||||
void setDrawFilters(DrawFilterFlags const * const filters, const SkString& configName) {
|
||||
fHasDrawFilters = false;
|
||||
fDrawFiltersConfig = configName;
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(fDrawFilters); ++i) {
|
||||
fDrawFilters[i] = filters[i];
|
||||
fHasDrawFilters |= SkToBool(filters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void setBBoxHierarchyType(BBoxHierarchyType bbhType) {
|
||||
fBBoxHierarchyType = bbhType;
|
||||
}
|
||||
|
||||
BBoxHierarchyType getBBoxHierarchyType() { return fBBoxHierarchyType; }
|
||||
|
||||
bool isUsingBitmapDevice() {
|
||||
return kBitmap_DeviceType == fDeviceType;
|
||||
}
|
||||
|
||||
virtual SkString getPerIterTimeFormat() { return SkString("%.2f"); }
|
||||
|
||||
virtual SkString getNormalTimeFormat() { return SkString("%6.2f"); }
|
||||
|
||||
/**
|
||||
* Reports the configuration of this PictureRenderer.
|
||||
*/
|
||||
SkString getConfigName() {
|
||||
SkString config = this->getConfigNameInternal();
|
||||
if (!fViewport.isEmpty()) {
|
||||
config.appendf("_viewport_%ix%i", fViewport.width(), fViewport.height());
|
||||
}
|
||||
if (fScaleFactor != SK_Scalar1) {
|
||||
config.appendf("_scalar_%f", SkScalarToFloat(fScaleFactor));
|
||||
}
|
||||
if (kRTree_BBoxHierarchyType == fBBoxHierarchyType) {
|
||||
config.append("_rtree");
|
||||
}
|
||||
#if SK_SUPPORT_GPU
|
||||
switch (fDeviceType) {
|
||||
case kGPU_DeviceType:
|
||||
if (fSampleCount) {
|
||||
config.appendf("_msaa%d", fSampleCount);
|
||||
} else if (fUseDFText) {
|
||||
config.append("_gpudft");
|
||||
} else {
|
||||
config.append("_gpu");
|
||||
}
|
||||
break;
|
||||
case kNVPR_DeviceType:
|
||||
config.appendf("_nvprmsaa%d", fSampleCount);
|
||||
break;
|
||||
#if SK_ANGLE
|
||||
case kAngle_DeviceType:
|
||||
config.append("_angle");
|
||||
break;
|
||||
#endif
|
||||
#if SK_COMMAND_BUFFER
|
||||
case kCommandBuffer_DeviceType:
|
||||
config.append("_commandbuffer");
|
||||
break;
|
||||
#endif
|
||||
#if SK_MESA
|
||||
case kMesa_DeviceType:
|
||||
config.append("_mesa");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
// Assume that no extra info means bitmap.
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
config.append(fDrawFiltersConfig.c_str());
|
||||
return config;
|
||||
}
|
||||
|
||||
Json::Value getJSONConfig() {
|
||||
Json::Value result;
|
||||
|
||||
result["mode"] = this->getConfigNameInternal().c_str();
|
||||
result["scale"] = 1.0f;
|
||||
if (SK_Scalar1 != fScaleFactor) {
|
||||
result["scale"] = SkScalarToFloat(fScaleFactor);
|
||||
}
|
||||
if (kRTree_BBoxHierarchyType == fBBoxHierarchyType) {
|
||||
result["bbh"] = "rtree";
|
||||
}
|
||||
#if SK_SUPPORT_GPU
|
||||
SkString tmp;
|
||||
switch (fDeviceType) {
|
||||
case kGPU_DeviceType:
|
||||
if (0 != fSampleCount) {
|
||||
tmp = "msaa";
|
||||
tmp.appendS32(fSampleCount);
|
||||
result["config"] = tmp.c_str();
|
||||
} else if (fUseDFText) {
|
||||
result["config"] = "gpudft";
|
||||
} else {
|
||||
result["config"] = "gpu";
|
||||
}
|
||||
break;
|
||||
case kNVPR_DeviceType:
|
||||
tmp = "nvprmsaa";
|
||||
tmp.appendS32(fSampleCount);
|
||||
result["config"] = tmp.c_str();
|
||||
break;
|
||||
#if SK_ANGLE
|
||||
case kAngle_DeviceType:
|
||||
result["config"] = "angle";
|
||||
break;
|
||||
#endif
|
||||
#if SK_COMMAND_BUFFER
|
||||
case kCommandBuffer_DeviceType:
|
||||
result["config"] = "commandbuffer";
|
||||
break;
|
||||
#endif
|
||||
#if SK_MESA
|
||||
case kMesa_DeviceType:
|
||||
result["config"] = "mesa";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
// Assume that no extra info means bitmap.
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool isUsingGpuDevice() {
|
||||
switch (fDeviceType) {
|
||||
case kGPU_DeviceType:
|
||||
case kNVPR_DeviceType:
|
||||
// fall through
|
||||
#if SK_ANGLE
|
||||
case kAngle_DeviceType:
|
||||
// fall through
|
||||
#endif
|
||||
#if SK_COMMAND_BUFFER
|
||||
case kCommandBuffer_DeviceType:
|
||||
// fall through
|
||||
#endif
|
||||
#if SK_MESA
|
||||
case kMesa_DeviceType:
|
||||
#endif
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SkGLContext* getGLContext() {
|
||||
return fGLContext;
|
||||
}
|
||||
|
||||
GrContext* getGrContext() {
|
||||
return fGrContext;
|
||||
}
|
||||
|
||||
const GrContextOptions& getGrContextOptions() {
|
||||
return fGrContextFactory.getGlobalOptions();
|
||||
}
|
||||
#endif
|
||||
|
||||
SkCanvas* getCanvas() {
|
||||
return fCanvas;
|
||||
}
|
||||
|
||||
const SkPicture* getPicture() {
|
||||
return fPicture;
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
explicit PictureRenderer(const GrContextOptions &opts)
|
||||
#else
|
||||
PictureRenderer()
|
||||
#endif
|
||||
: fDeviceType(kBitmap_DeviceType)
|
||||
, fBBoxHierarchyType(kNone_BBoxHierarchyType)
|
||||
, fHasDrawFilters(false)
|
||||
, fScaleFactor(SK_Scalar1)
|
||||
#if SK_SUPPORT_GPU
|
||||
, fGrContextFactory(opts)
|
||||
, fSampleCount(0)
|
||||
, fUseDFText(false)
|
||||
#endif
|
||||
{
|
||||
sk_bzero(fDrawFilters, sizeof(fDrawFilters));
|
||||
fViewport.set(0, 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
SkAutoTUnref<SkCanvas> fCanvas;
|
||||
SkAutoTUnref<const SkPicture> fPicture;
|
||||
bool fUseChecksumBasedFilenames;
|
||||
bool fUseMultiPictureDraw;
|
||||
SkDeviceTypes fDeviceType;
|
||||
BBoxHierarchyType fBBoxHierarchyType;
|
||||
bool fHasDrawFilters;
|
||||
DrawFilterFlags fDrawFilters[SkDrawFilter::kTypeCount];
|
||||
SkString fDrawFiltersConfig;
|
||||
SkString fWritePath;
|
||||
SkString fMismatchPath;
|
||||
SkString fInputFilename;
|
||||
|
||||
void buildBBoxHierarchy();
|
||||
|
||||
/**
|
||||
* Return the total width that should be drawn. If the viewport width has been set greater than
|
||||
* 0, this will be the minimum of the current SkPicture's width and the viewport's width.
|
||||
*/
|
||||
int getViewWidth();
|
||||
|
||||
/**
|
||||
* Return the total height that should be drawn. If the viewport height has been set greater
|
||||
* than 0, this will be the minimum of the current SkPicture's height and the viewport's height.
|
||||
*/
|
||||
int getViewHeight();
|
||||
|
||||
/**
|
||||
* Scales the provided canvas to the scale factor set by setScaleFactor.
|
||||
*/
|
||||
void scaleToScaleFactor(SkCanvas*);
|
||||
|
||||
SkBBHFactory* getFactory();
|
||||
uint32_t recordFlags() const { return 0; }
|
||||
SkCanvas* setupCanvas();
|
||||
virtual SkCanvas* setupCanvas(int width, int height);
|
||||
|
||||
/**
|
||||
* Copy src to dest; if src==nullptr, set dest to empty string.
|
||||
*/
|
||||
static void CopyString(SkString* dest, const SkString* src);
|
||||
|
||||
private:
|
||||
SkISize fViewport;
|
||||
SkScalar fScaleFactor;
|
||||
#if SK_SUPPORT_GPU
|
||||
GrContextFactory fGrContextFactory;
|
||||
SkAutoTUnref<GrContext> fGrContext;
|
||||
SkAutoTUnref<SkGLContext> fGLContext;
|
||||
int fSampleCount;
|
||||
bool fUseDFText;
|
||||
#endif
|
||||
|
||||
virtual SkString getConfigNameInternal() = 0;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class does not do any rendering, but its render function executes recording, which we want
|
||||
* to time.
|
||||
*/
|
||||
class RecordPictureRenderer : public PictureRenderer {
|
||||
public:
|
||||
#if SK_SUPPORT_GPU
|
||||
RecordPictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
|
||||
#endif
|
||||
|
||||
bool render(SkBitmap** out = nullptr) override;
|
||||
|
||||
SkString getPerIterTimeFormat() override { return SkString("%.4f"); }
|
||||
|
||||
SkString getNormalTimeFormat() override { return SkString("%6.4f"); }
|
||||
|
||||
protected:
|
||||
SkCanvas* setupCanvas(int width, int height) override;
|
||||
|
||||
private:
|
||||
SkString getConfigNameInternal() override;
|
||||
|
||||
typedef PictureRenderer INHERITED;
|
||||
};
|
||||
|
||||
class PipePictureRenderer : public PictureRenderer {
|
||||
public:
|
||||
#if SK_SUPPORT_GPU
|
||||
PipePictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
|
||||
#endif
|
||||
|
||||
bool render(SkBitmap** out = nullptr) override;
|
||||
|
||||
private:
|
||||
SkString getConfigNameInternal() override;
|
||||
|
||||
typedef PictureRenderer INHERITED;
|
||||
};
|
||||
|
||||
class SimplePictureRenderer : public PictureRenderer {
|
||||
public:
|
||||
#if SK_SUPPORT_GPU
|
||||
SimplePictureRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
|
||||
#endif
|
||||
|
||||
virtual void init(const SkPicture* pict,
|
||||
const SkString* writePath,
|
||||
const SkString* mismatchPath,
|
||||
const SkString* inputFilename,
|
||||
bool useChecksumBasedFilenames,
|
||||
bool useMultiPictureDraw) override;
|
||||
|
||||
bool render(SkBitmap** out = nullptr) override;
|
||||
|
||||
private:
|
||||
SkString getConfigNameInternal() override;
|
||||
|
||||
typedef PictureRenderer INHERITED;
|
||||
};
|
||||
|
||||
class TiledPictureRenderer : public PictureRenderer {
|
||||
public:
|
||||
#if SK_SUPPORT_GPU
|
||||
TiledPictureRenderer(const GrContextOptions &opts);
|
||||
#else
|
||||
TiledPictureRenderer();
|
||||
#endif
|
||||
|
||||
virtual void init(const SkPicture* pict,
|
||||
const SkString* writePath,
|
||||
const SkString* mismatchPath,
|
||||
const SkString* inputFilename,
|
||||
bool useChecksumBasedFilenames,
|
||||
bool useMultiPictureDraw) override;
|
||||
|
||||
/**
|
||||
* Renders to tiles, rather than a single canvas.
|
||||
* If fWritePath was provided, a separate file is
|
||||
* created for each tile, named "path0.png", "path1.png", etc.
|
||||
*/
|
||||
bool render(SkBitmap** out = nullptr) override;
|
||||
|
||||
void end() override;
|
||||
|
||||
void setTileWidth(int width) {
|
||||
fTileWidth = width;
|
||||
}
|
||||
|
||||
int getTileWidth() const {
|
||||
return fTileWidth;
|
||||
}
|
||||
|
||||
void setTileHeight(int height) {
|
||||
fTileHeight = height;
|
||||
}
|
||||
|
||||
int getTileHeight() const {
|
||||
return fTileHeight;
|
||||
}
|
||||
|
||||
void setTileWidthPercentage(double percentage) {
|
||||
fTileWidthPercentage = percentage;
|
||||
}
|
||||
|
||||
double getTileWidthPercentage() const {
|
||||
return fTileWidthPercentage;
|
||||
}
|
||||
|
||||
void setTileHeightPercentage(double percentage) {
|
||||
fTileHeightPercentage = percentage;
|
||||
}
|
||||
|
||||
double getTileHeightPercentage() const {
|
||||
return fTileHeightPercentage;
|
||||
}
|
||||
|
||||
void setTileMinPowerOf2Width(int width) {
|
||||
SkASSERT(SkIsPow2(width) && width > 0);
|
||||
if (!SkIsPow2(width) || width <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
fTileMinPowerOf2Width = width;
|
||||
}
|
||||
|
||||
int getTileMinPowerOf2Width() const {
|
||||
return fTileMinPowerOf2Width;
|
||||
}
|
||||
|
||||
TiledPictureRenderer* getTiledRenderer() override { return this; }
|
||||
|
||||
virtual bool supportsTimingIndividualTiles() { return true; }
|
||||
|
||||
/**
|
||||
* Report the number of tiles in the x and y directions. Must not be called before init.
|
||||
* @param x Output parameter identifying the number of tiles in the x direction.
|
||||
* @param y Output parameter identifying the number of tiles in the y direction.
|
||||
* @return True if the tiles have been set up, and x and y are meaningful. If false, x and y are
|
||||
* unmodified.
|
||||
*/
|
||||
bool tileDimensions(int& x, int&y);
|
||||
|
||||
/**
|
||||
* Move to the next tile and return its indices. Must be called before calling drawCurrentTile
|
||||
* for the first time.
|
||||
* @param i Output parameter identifying the column of the next tile to be drawn on the next
|
||||
* call to drawNextTile.
|
||||
* @param j Output parameter identifying the row of the next tile to be drawn on the next call
|
||||
* to drawNextTile.
|
||||
* @param True if the tiles have been created and the next tile to be drawn by drawCurrentTile
|
||||
* is within the range of tiles. If false, i and j are unmodified.
|
||||
*/
|
||||
bool nextTile(int& i, int& j);
|
||||
|
||||
/**
|
||||
* Render one tile. This will draw the same tile each time it is called until nextTile is
|
||||
* called. The tile rendered will depend on how many calls have been made to nextTile.
|
||||
* It is an error to call this without first calling nextTile, or if nextTile returns false.
|
||||
*/
|
||||
void drawCurrentTile();
|
||||
|
||||
protected:
|
||||
SkTDArray<SkIRect> fTileRects;
|
||||
|
||||
SkCanvas* setupCanvas(int width, int height) override;
|
||||
SkString getConfigNameInternal() override;
|
||||
|
||||
private:
|
||||
int fTileWidth;
|
||||
int fTileHeight;
|
||||
double fTileWidthPercentage;
|
||||
double fTileHeightPercentage;
|
||||
int fTileMinPowerOf2Width;
|
||||
|
||||
// These variables are only used for timing individual tiles.
|
||||
// Next tile to draw in fTileRects.
|
||||
int fCurrentTileOffset;
|
||||
// Number of tiles in the x direction.
|
||||
int fTilesX;
|
||||
// Number of tiles in the y direction.
|
||||
int fTilesY;
|
||||
|
||||
void setupTiles();
|
||||
void setupPowerOf2Tiles();
|
||||
bool postRender(SkCanvas*, const SkIRect& tileRect,
|
||||
SkBitmap* tempBM, SkBitmap** out,
|
||||
int tileNumber);
|
||||
|
||||
typedef PictureRenderer INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class does not do any rendering, but its render function executes turning an SkPictureRecord
|
||||
* into an SkPicturePlayback, which we want to time.
|
||||
*/
|
||||
class PlaybackCreationRenderer : public PictureRenderer {
|
||||
public:
|
||||
#if SK_SUPPORT_GPU
|
||||
PlaybackCreationRenderer(const GrContextOptions &opts) : INHERITED(opts) { }
|
||||
#endif
|
||||
|
||||
void setup() override;
|
||||
|
||||
bool render(SkBitmap** out = nullptr) override;
|
||||
|
||||
SkString getPerIterTimeFormat() override { return SkString("%.4f"); }
|
||||
|
||||
SkString getNormalTimeFormat() override { return SkString("%6.4f"); }
|
||||
|
||||
private:
|
||||
SkAutoTDelete<SkPictureRecorder> fRecorder;
|
||||
|
||||
SkString getConfigNameInternal() override;
|
||||
|
||||
typedef PictureRenderer INHERITED;
|
||||
};
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
extern PictureRenderer* CreateGatherPixelRefsRenderer(const GrContextOptions& opts);
|
||||
#else
|
||||
extern PictureRenderer* CreateGatherPixelRefsRenderer();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif // PictureRenderer_DEFINED
|
Loading…
Reference in New Issue
Block a user