Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
TextureUploadSlide.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2019 Google Inc. and Adobe Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
15#include "tools/viewer/Slide.h"
16
17using namespace skia_private;
18
19/**
20 * This sample exercises heavy texture updates and uploads.
21 */
22class TextureUploadSlide : public Slide {
23public:
24 TextureUploadSlide() { fName = "TextureUpload"; }
25
26 bool onChar(SkUnichar uni) override {
27 if ('m' == uni) {
28 fDrawTexturesToScreen = !fDrawTexturesToScreen;
29 return true;
30 } else if ('>' == uni) {
31 fTileSize = std::min(kMaxTileSize, 2*fTileSize);
32 fTileRows = kMaxTileSize/fTileSize;
33 fTileCols = kMaxTileSize/fTileSize;
34 fCachedContext = nullptr;
35 } else if ('<' == uni) {
36 fTileSize = std::max(kMinTileSize, fTileSize/2);
37 fTileRows = kMaxTileSize/fTileSize;
38 fTileCols = kMaxTileSize/fTileSize;
39 fCachedContext = nullptr;
40 }
41 return false;
42 }
43
44 SkISize getDimensions() const override { return {1024, 1024}; }
45
46 void draw(SkCanvas* canvas) override {
47 canvas->clear(0xFFFFFFFF);
48#if defined(SK_GANESH)
49 auto direct = GrAsDirectContext(canvas->recordingContext());
50 if (direct) {
51 // One-time context-specific setup.
52 if (direct != fCachedContext) {
53 fCachedContext = direct;
54 this->initializeTextures(direct);
55 }
56
57 // Upload new texture data for all textures, simulating a full page of tiles
58 // needing refresh.
59 int textureCount = fTileRows * fTileCols;
60 for (int i = 0; i < textureCount; i++) {
61 fTextures[i]->uploadRasterSurface(i == fActiveTileIndex ? fBlueSurface
62 : fGraySurface);
63 }
64
65 // Scale grid.
66 canvas->scale(kGridScale, kGridScale);
67
68 if (fDrawTexturesToScreen) {
69 for (int y = 0; y < fTileRows; y++) {
70 for (int x = 0; x < fTileCols; x++) {
71 int currentIndex = y * fTileCols + x;
72 canvas->drawImage(fTextures[currentIndex]->getImage(),
73 x * fTileSize, y * fTileSize);
74 }
75 }
76 }
77 }
78#endif
79 }
80
81 bool animate(double nanos) override {
82 constexpr SkScalar kDesiredDurationSecs = 16.0f;
83 float numTiles = fTileRows*fTileCols;
84 fActiveTileIndex = floorf(TimeUtils::Scaled(1e-9 * nanos,
85 numTiles/kDesiredDurationSecs, numTiles));
86 return true;
87 }
88
89private:
90 class RenderTargetTexture : public SkRefCnt {
91 public:
92 RenderTargetTexture(GrDirectContext* direct, int size) {
96 fSurface = SkSurfaces::RenderTarget(
97 direct, skgpu::Budgeted::kNo, imageInfo, 0, &surfaceProps);
98 }
99
100 sk_sp<SkImage> getImage() {
101 return fSurface->makeImageSnapshot();
102 }
103
104 void uploadRasterSurface(sk_sp<SkSurface> rasterSurface) {
105 SkPixmap pixmap;
106 rasterSurface->peekPixels(&pixmap);
107 fSurface->writePixels(pixmap, 0, 0);
108 }
109
110 private:
111 sk_sp<SkSurface> fSurface;
112 sk_sp<SkImage> fCachedImage;
113 };
114
115 inline static constexpr int kMinTileSize = 128;
116 inline static constexpr int kMaxTileSize = 2048;
117 inline static constexpr float kGridScale = 0.25f;
118
119 bool fDrawTexturesToScreen = true;
120 int fTileSize = 256;
121 int fTileRows = 8;
122 int fTileCols = 8;
123
124 sk_sp<SkSurface> fBlueSurface;
125 sk_sp<SkSurface> fGraySurface;
126
128
129 GrDirectContext* fCachedContext = nullptr;
130
131 SkScalar fActiveTileIndex = 0;
132
133 sk_sp<SkSurface> getFilledRasterSurface(SkColor color, int size) {
135 SkCanvas* canvas = surface->getCanvas();
136 canvas->clear(color);
137 return surface;
138 }
139 void initializeTextures(GrDirectContext* direct) {
140 fTextures.clear();
141 int textureCount = fTileRows * fTileCols;
142 for (int i = 0; i < textureCount; i++) {
143 fTextures.emplace_back(new RenderTargetTexture(direct, fTileSize));
144 }
145
146 // Construct two simple rasters of differing colors to serve
147 // as cpu rasterized data to refresh textures with.
148 fBlueSurface = this->getFilledRasterSurface(SK_ColorBLUE, fTileSize);
149 fGraySurface = this->getFilledRasterSurface(SK_ColorGRAY, fTileSize);
150 }
151};
152
153
154DEF_SLIDE( return new TextureUploadSlide(); )
155
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
SkColor4f color
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorGRAY
Definition SkColor.h:113
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
@ kRGB_H_SkPixelGeometry
int32_t SkUnichar
Definition SkTypes.h:175
#define DEF_SLIDE(code)
Definition Slide.h:25
virtual GrRecordingContext * recordingContext() const
void clear(SkColor color)
Definition SkCanvas.h:1199
void scale(SkScalar sx, SkScalar sy)
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
Definition Slide.h:29
SkString fName
Definition Slide.h:54
bool onChar(SkUnichar uni) override
bool animate(double nanos) override
void draw(SkCanvas *canvas) override
SkISize getDimensions() const override
T & emplace_back(Args &&... args)
Definition SkTArray.h:243
VkSurfaceKHR surface
Definition main.cc:49
float SkScalar
Definition extension.cpp:12
double y
double x
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
static float Scaled(float time, float speed, float period=0)
Definition TimeUtils.h:27
static SkImageInfo MakeN32Premul(int width, int height)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)