support gpu for skottie2movie
-g will try to render the frames using OpenGL
For the motion-blur test skottie on Mac Pro...
Before: 71.0 secs
After : 6.6 secs
Change-Id: I7e723d4ac0bb63b0e42381ed50bf2144dfc9c8a3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/243428
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/tools/skottie2movie.cpp b/tools/skottie2movie.cpp
index fa98b2a..48d5dee 100644
--- a/tools/skottie2movie.cpp
+++ b/tools/skottie2movie.cpp
@@ -14,7 +14,11 @@
#include "modules/skottie/include/Skottie.h"
#include "modules/skottie/utils/SkottieUtils.h"
#include "src/utils/SkOSPath.h"
+
#include "tools/flags/CommandLineFlags.h"
+#include "tools/gpu/GrContextFactory.h"
+
+#include "include/gpu/GrContextOptions.h"
static DEFINE_string2(input, i, "", "skottie animation to render");
static DEFINE_string2(output, o, "", "mp4 file to create");
@@ -23,6 +27,7 @@
static DEFINE_bool2(verbose, v, false, "verbose mode");
static DEFINE_bool2(loop, l, false, "loop mode for profiling");
static DEFINE_int(set_dst_width, 0, "set destination width (height will be computed)");
+static DEFINE_bool2(gpu, g, false, "use GPU for rendering");
static void produce_frame(SkSurface* surf, skottie::Animation* anim, double frame_time) {
anim->seekFrameTime(frame_time);
@@ -30,6 +35,11 @@
anim->render(surf->getCanvas());
}
+struct AsyncRec {
+ SkImageInfo info;
+ SkVideoEncoder* encoder;
+};
+
int main(int argc, char** argv) {
SkGraphics::Init();
@@ -41,6 +51,10 @@
return -1;
}
+ auto contextType = sk_gpu_test::GrContextFactory::kGL_ContextType;
+ GrContextOptions grCtxOptions;
+ sk_gpu_test::GrContextFactory factory(grCtxOptions);
+
SkString assetPath;
if (FLAGS_assetPath.count() > 0) {
assetPath.set(FLAGS_assetPath[0]);
@@ -82,20 +96,34 @@
SkVideoEncoder encoder;
- sk_sp<SkSurface> surf, tmp_surf;
+ GrContext* context = nullptr;
+ sk_sp<SkSurface> surf;
sk_sp<SkData> data;
do {
double loop_start = SkTime::GetSecs();
encoder.beginRecording(dim, fps);
+ auto info = encoder.preferredInfo();
+
// lazily allocate the surfaces
if (!surf) {
- surf = SkSurface::MakeRaster(encoder.preferredInfo());
- tmp_surf = surf->makeSurface(surf->width(), surf->height());
-
- surf->getCanvas()->scale(scale, scale);
- tmp_surf->getCanvas()->scale(scale, scale);
+ if (FLAGS_gpu) {
+ context = factory.getContextInfo(contextType).grContext();
+ surf = SkSurface::MakeRenderTarget(context,
+ SkBudgeted::kNo,
+ info,
+ 0,
+ GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
+ nullptr);
+ if (!surf) {
+ context = nullptr;
+ }
+ }
+ if (!surf) {
+ surf = SkSurface::MakeRaster(info);
+ }
+ surf->getCanvas()->scale(scale, scale);
}
for (int i = 0; i <= frames; ++i) {
@@ -109,9 +137,19 @@
produce_frame(surf.get(), animation.get(), frame_time);
- SkPixmap pm;
- SkAssertResult(surf->peekPixels(&pm));
- encoder.addFrame(pm);
+ AsyncRec asyncRec = { info, &encoder };
+ if (context) {
+ surf->asyncRescaleAndReadPixels(info, {0, 0, info.width(), info.height()},
+ SkSurface::RescaleGamma::kSrc, kNone_SkFilterQuality,
+ [](void* ctx, const void* data, size_t rb) {
+ AsyncRec* rec = (AsyncRec*)ctx;
+ rec->encoder->addFrame({rec->info, data, rb});
+ }, &asyncRec);
+ } else {
+ SkPixmap pm;
+ SkAssertResult(surf->peekPixels(&pm));
+ encoder.addFrame(pm);
+ }
}
data = encoder.endRecording();