1799a3646f9e1331bbfd82c5a34d1b47e279420f9reed/*
2799a3646f9e1331bbfd82c5a34d1b47e279420f9reed * Copyright 2015 Google Inc.
3799a3646f9e1331bbfd82c5a34d1b47e279420f9reed *
4799a3646f9e1331bbfd82c5a34d1b47e279420f9reed * Use of this source code is governed by a BSD-style license that can be
5799a3646f9e1331bbfd82c5a34d1b47e279420f9reed * found in the LICENSE file.
6799a3646f9e1331bbfd82c5a34d1b47e279420f9reed */
7799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
8799a3646f9e1331bbfd82c5a34d1b47e279420f9reed#include "Benchmark.h"
9799a3646f9e1331bbfd82c5a34d1b47e279420f9reed#include "SkCanvas.h"
10799a3646f9e1331bbfd82c5a34d1b47e279420f9reed#include "SkImage.h"
11799a3646f9e1331bbfd82c5a34d1b47e279420f9reed#include "SkSurface.h"
12799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
13dea6e1c737a97a10e123d811d056ff85a09e1f2ereedclass Image2RasterBench : public Benchmark {
14799a3646f9e1331bbfd82c5a34d1b47e279420f9reedpublic:
15dea6e1c737a97a10e123d811d056ff85a09e1f2ereed    Image2RasterBench() {
16dea6e1c737a97a10e123d811d056ff85a09e1f2ereed        fName.set("native_image_to_raster_surface");
17799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    }
18799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
19799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    bool isSuitableFor(Backend backend) override {
20dea6e1c737a97a10e123d811d056ff85a09e1f2ereed        return kGPU_Backend == backend || kRaster_Backend == backend;
21799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    }
22799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
23799a3646f9e1331bbfd82c5a34d1b47e279420f9reedprotected:
24799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    const char* onGetName() override {
25799a3646f9e1331bbfd82c5a34d1b47e279420f9reed        return fName.c_str();
26799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    }
27799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
28dea6e1c737a97a10e123d811d056ff85a09e1f2ereed    // We explicitly want to bench drawing a Image [cpu or gpu backed] into a raster target,
29dea6e1c737a97a10e123d811d056ff85a09e1f2ereed    // to ensure that we can cache the read-back in the case of gpu -> raster
30dea6e1c737a97a10e123d811d056ff85a09e1f2ereed    //
31799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    void onPerCanvasPreDraw(SkCanvas* canvas) override {
32dea6e1c737a97a10e123d811d056ff85a09e1f2ereed        // create an Image reflecting the canvas (gpu or cpu)
330ce3d43df9cbada290008efcb183cedbcbe0aeedBrian Osman        SkImageInfo info = canvas->imageInfo().makeWH(100, 100);
34e8f3062a36d3682f4019309a32b5b84dc9eddf8creed        auto surface(canvas->makeSurface(info));
35799a3646f9e1331bbfd82c5a34d1b47e279420f9reed        canvas->drawColor(SK_ColorRED);
369ce9d6772df650ceb0511f275e1a83dffa78ff72reed        fImage = surface->makeImageSnapshot();
37799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
38799a3646f9e1331bbfd82c5a34d1b47e279420f9reed        // create a cpu-backed Surface
390ce3d43df9cbada290008efcb183cedbcbe0aeedBrian Osman        SkImageInfo n32Info = SkImageInfo::MakeN32Premul(100, 100);
400ce3d43df9cbada290008efcb183cedbcbe0aeedBrian Osman        fRasterSurface = SkSurface::MakeRaster(n32Info);
41799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    }
42799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
434870e6d4c9ee76ee328969e82238c7adc371fd33hendrikw    void onPerCanvasPostDraw(SkCanvas*) override {
444870e6d4c9ee76ee328969e82238c7adc371fd33hendrikw        // Release the image and raster surface here to prevent out of order destruction
454870e6d4c9ee76ee328969e82238c7adc371fd33hendrikw        // between these and the gpu interface.
464870e6d4c9ee76ee328969e82238c7adc371fd33hendrikw        fRasterSurface.reset(nullptr);
474870e6d4c9ee76ee328969e82238c7adc371fd33hendrikw        fImage.reset(nullptr);
484870e6d4c9ee76ee328969e82238c7adc371fd33hendrikw    }
494870e6d4c9ee76ee328969e82238c7adc371fd33hendrikw
50a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas*) override {
51799a3646f9e1331bbfd82c5a34d1b47e279420f9reed        for (int i = 0; i < loops; i++) {
52799a3646f9e1331bbfd82c5a34d1b47e279420f9reed            for (int inner = 0; inner < 10; ++inner) {
539ce9d6772df650ceb0511f275e1a83dffa78ff72reed                fRasterSurface->getCanvas()->drawImage(fImage.get(), 0, 0);
54799a3646f9e1331bbfd82c5a34d1b47e279420f9reed            }
55799a3646f9e1331bbfd82c5a34d1b47e279420f9reed        }
56799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    }
57799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
58799a3646f9e1331bbfd82c5a34d1b47e279420f9reedprivate:
59799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    SkString                fName;
609ce9d6772df650ceb0511f275e1a83dffa78ff72reed    sk_sp<SkImage>   fImage;
61e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    sk_sp<SkSurface> fRasterSurface;
62799a3646f9e1331bbfd82c5a34d1b47e279420f9reed
63799a3646f9e1331bbfd82c5a34d1b47e279420f9reed    typedef Benchmark INHERITED;
64799a3646f9e1331bbfd82c5a34d1b47e279420f9reed};
656f2753deee7b8cd03224e3df91dfea21bbeb9f7freedDEF_BENCH( return new Image2RasterBench; )
66