Support using OpenGL ES context on desktop
Support using OpenGL ES context on desktop for unix and Android platforms. This
is mainly useful in development.
Add --gpuAPI flag to gm, dm, bench, bench_pictures and render_pictures. The
possible parameters for the flag are "gl" and "gles".
R=bsalomon@google.com, mtklein@google.com, robertphillips@google.com
Author: kkinnunen@nvidia.com
Review URL: https://codereview.chromium.org/319043005
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 64a4bc5..afe7573 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -37,8 +37,15 @@
using skiatest::Test;
using skiatest::TestRegistry;
+static const char kGpuAPINameGL[] = "gl";
+static const char kGpuAPINameGLES[] = "gles";
+
DEFINE_int32(threads, -1, "Threads for CPU work. Default NUM_CPUS.");
DEFINE_int32(gpuThreads, 1, "Threads for GPU work.");
+DEFINE_string(gpuAPI, "", "Force use of specific gpu API. Using \"gl\" "
+ "forces OpenGL API. Using \"gles\" forces OpenGL ES API. "
+ "Defaults to empty string, which selects the API native to the "
+ "system.");
DEFINE_string2(expectations, r, "",
"If a directory, compare generated images against images under this path. "
"If a file, compare generated images against JSON expectations at this path."
@@ -95,6 +102,7 @@
static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
const SkTArray<SkString>& configs,
+ GrGLStandard gpuAPI,
const DM::Expectations& expectations,
DM::Reporter* reporter,
DM::TaskRunner* tasks) {
@@ -104,17 +112,18 @@
}
for (int i = 0; i < gms.count(); i++) {
for (int j = 0; j < configs.count(); j++) {
+
START("565", CpuGMTask, expectations, kRGB_565_SkColorType);
START("8888", CpuGMTask, expectations, kN32_SkColorType);
- START("gpu", GpuGMTask, expectations, native, 0);
- START("msaa4", GpuGMTask, expectations, native, 4);
- START("msaa16", GpuGMTask, expectations, native, 16);
- START("nvprmsaa4", GpuGMTask, expectations, nvpr, 4);
- START("nvprmsaa16", GpuGMTask, expectations, nvpr, 16);
- START("gpunull", GpuGMTask, expectations, null, 0);
- START("gpudebug", GpuGMTask, expectations, debug, 0);
- START("angle", GpuGMTask, expectations, angle, 0);
- START("mesa", GpuGMTask, expectations, mesa, 0);
+ START("gpu", GpuGMTask, expectations, native, gpuAPI, 0);
+ START("msaa4", GpuGMTask, expectations, native, gpuAPI, 4);
+ START("msaa16", GpuGMTask, expectations, native, gpuAPI, 16);
+ START("nvprmsaa4", GpuGMTask, expectations, nvpr, gpuAPI, 4);
+ START("nvprmsaa16", GpuGMTask, expectations, nvpr, gpuAPI, 16);
+ START("gpunull", GpuGMTask, expectations, null, gpuAPI, 0);
+ START("gpudebug", GpuGMTask, expectations, debug, gpuAPI, 0);
+ START("angle", GpuGMTask, expectations, angle, gpuAPI, 0);
+ START("mesa", GpuGMTask, expectations, mesa, gpuAPI, 0);
START("pdf", PDFTask, RASTERIZE_PDF_PROC);
}
}
@@ -123,6 +132,7 @@
static void kick_off_benches(const SkTDArray<BenchRegistry::Factory>& benches,
const SkTArray<SkString>& configs,
+ GrGLStandard gpuAPI,
DM::Reporter* reporter,
DM::TaskRunner* tasks) {
#define START(name, type, ...) \
@@ -134,15 +144,15 @@
START("nonrendering", NonRenderingBenchTask);
START("565", CpuBenchTask, kRGB_565_SkColorType);
START("8888", CpuBenchTask, kN32_SkColorType);
- START("gpu", GpuBenchTask, native, 0);
- START("msaa4", GpuBenchTask, native, 4);
- START("msaa16", GpuBenchTask, native, 16);
- START("nvprmsaa4", GpuBenchTask, nvpr, 4);
- START("nvprmsaa16", GpuBenchTask, nvpr, 16);
- START("gpunull", GpuBenchTask, null, 0);
- START("gpudebug", GpuBenchTask, debug, 0);
- START("angle", GpuBenchTask, angle, 0);
- START("mesa", GpuBenchTask, mesa, 0);
+ START("gpu", GpuBenchTask, native, gpuAPI, 0);
+ START("msaa4", GpuBenchTask, native, gpuAPI, 4);
+ START("msaa16", GpuBenchTask, native, gpuAPI, 16);
+ START("nvprmsaa4", GpuBenchTask, nvpr, gpuAPI, 4);
+ START("nvprmsaa16", GpuBenchTask, nvpr, gpuAPI, 16);
+ START("gpunull", GpuBenchTask, null, gpuAPI, 0);
+ START("gpudebug", GpuBenchTask, debug, gpuAPI, 0);
+ START("angle", GpuBenchTask, angle, gpuAPI, 0);
+ START("mesa", GpuBenchTask, mesa, gpuAPI, 0);
}
}
#undef START
@@ -204,6 +214,16 @@
SkDebugf("%d failures.\n", failures.count());
}
+static GrGLStandard get_gl_standard() {
+ if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
+ return kGL_GrGLStandard;
+ }
+ if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
+ return kGLES_GrGLStandard;
+ }
+ return kNone_GrGLStandard;
+}
+
template <typename T, typename Registry>
static void append_matching_factories(Registry* head, SkTDArray<typename Registry::Factory>* out) {
for (const Registry* reg = head; reg != NULL; reg = reg->next()) {
@@ -232,6 +252,8 @@
SkStrSplit(FLAGS_config[i], ", ", &configs);
}
+ GrGLStandard gpuAPI = get_gl_standard();
+
SkTDArray<GMRegistry::Factory> gms;
SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
if (FLAGS_gms) {
@@ -261,8 +283,8 @@
gms.count(), benches.count(), configs.count(), tests.count());
DM::Reporter reporter;
DM::TaskRunner tasks(FLAGS_threads, FLAGS_gpuThreads);
- kick_off_gms(gms, configs, *expectations, &reporter, &tasks);
- kick_off_benches(benches, configs, &reporter, &tasks);
+ kick_off_gms(gms, configs, gpuAPI, *expectations, &reporter, &tasks);
+ kick_off_benches(benches, configs, gpuAPI, &reporter, &tasks);
kick_off_tests(tests, &reporter, &tasks);
kick_off_skps(&reporter, &tasks);
tasks.wait();
diff --git a/dm/DMBenchTask.cpp b/dm/DMBenchTask.cpp
index 7cd2fdc..9bdbbf2 100644
--- a/dm/DMBenchTask.cpp
+++ b/dm/DMBenchTask.cpp
@@ -33,11 +33,13 @@
TaskRunner* tasks,
BenchRegistry::Factory factory,
GrContextFactory::GLContextType contextType,
+ GrGLStandard gpuAPI,
int sampleCount)
: GpuTask(reporter, tasks)
, fBench(factory(NULL))
, fName(bench_name(fBench->getName(), config))
, fContextType(contextType)
+ , fGpuAPI(gpuAPI)
, fSampleCount(sampleCount) {}
bool NonRenderingBenchTask::shouldSkip() const {
@@ -74,8 +76,12 @@
fBench->getSize().y(),
kN32_SkColorType,
kPremul_SkAlphaType);
- SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, info, fSampleCount));
-
+ SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, fGpuAPI, info,
+ fSampleCount));
+ if (!surface) {
+ this->fail("Could not create context for the config and the api.");
+ return;
+ }
fBench->preDraw();
fBench->draw(1, surface->getCanvas());
}
diff --git a/dm/DMBenchTask.h b/dm/DMBenchTask.h
index 3c71cd7..d2b5800 100644
--- a/dm/DMBenchTask.h
+++ b/dm/DMBenchTask.h
@@ -46,6 +46,7 @@
TaskRunner*,
BenchRegistry::Factory,
GrContextFactory::GLContextType,
+ GrGLStandard gpuAPI,
int sampleCount);
virtual void draw(GrContextFactory*) SK_OVERRIDE;
@@ -56,6 +57,7 @@
SkAutoTDelete<Benchmark> fBench;
const SkString fName;
const GrContextFactory::GLContextType fContextType;
+ const GrGLStandard fGpuAPI;
int fSampleCount;
};
diff --git a/dm/DMGpuGMTask.cpp b/dm/DMGpuGMTask.cpp
index b384485..4c44fae 100644
--- a/dm/DMGpuGMTask.cpp
+++ b/dm/DMGpuGMTask.cpp
@@ -15,12 +15,14 @@
skiagm::GMRegistry::Factory gmFactory,
const Expectations& expectations,
GrContextFactory::GLContextType contextType,
+ GrGLStandard gpuAPI,
int sampleCount)
: GpuTask(reporter, taskRunner)
, fGM(gmFactory(NULL))
, fName(UnderJoin(fGM->getName(), config))
, fExpectations(expectations)
, fContextType(contextType)
+ , fGpuAPI(gpuAPI)
, fSampleCount(sampleCount)
{}
@@ -29,7 +31,12 @@
SkScalarCeilToInt(fGM->height()),
kN32_SkColorType,
kPremul_SkAlphaType);
- SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, info, fSampleCount));
+ SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, fGpuAPI, info,
+ fSampleCount));
+ if (!surface) {
+ this->fail("Could not create context for the config and the api.");
+ return;
+ }
SkCanvas* canvas = surface->getCanvas();
canvas->concat(fGM->getInitialTransform());
diff --git a/dm/DMGpuGMTask.h b/dm/DMGpuGMTask.h
index 6621a49..46b4c98 100644
--- a/dm/DMGpuGMTask.h
+++ b/dm/DMGpuGMTask.h
@@ -23,6 +23,7 @@
skiagm::GMRegistry::Factory,
const Expectations&,
GrContextFactory::GLContextType,
+ GrGLStandard gpuAPI,
int sampleCount);
virtual void draw(GrContextFactory*) SK_OVERRIDE;
@@ -34,6 +35,7 @@
const SkString fName;
const Expectations& fExpectations;
const GrContextFactory::GLContextType fContextType;
+ GrGLStandard fGpuAPI;
const int fSampleCount;
};
diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h
index 46896b4..bcc00c2 100644
--- a/dm/DMGpuSupport.h
+++ b/dm/DMGpuSupport.h
@@ -19,9 +19,10 @@
static inline SkSurface* NewGpuSurface(GrContextFactory* grFactory,
GrContextFactory::GLContextType type,
+ GrGLStandard gpuAPI,
SkImageInfo info,
int samples) {
- return SkSurface::NewRenderTarget(grFactory->get(type), info, samples);
+ return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI), info, samples);
}
} // namespace DM
@@ -30,6 +31,12 @@
// Ganesh is not available. Fake it.
+enum GrGLStandard {
+ kNone_GrGLStandard,
+ kGL_GrGLStandard,
+ kGLES_GrGLStandard
+};
+
class GrContextFactory {
public:
typedef int GLContextType;
@@ -48,6 +55,7 @@
static inline SkSurface* NewGpuSurface(GrContextFactory*,
GrContextFactory::GLContextType,
+ GrGLStandard,
SkImageInfo,
int) {
return NULL;