Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ProtectedSlide.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
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
9
10#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
11
15#include "tools/ToolUtils.h"
16#include "tools/viewer/Slide.h"
17
18#if defined(SK_GANESH)
23#endif
24
25#if defined(SK_GRAPHITE)
30
31#else
32namespace skgpu::graphite {
33 class Recorder;
34}
35#endif
36
38
39using namespace skgpu::graphite;
40
41namespace {
42
43static void release_buffer(AHardwareBuffer* buffer) {
44 if (buffer) {
45 AHardwareBuffer_release(buffer);
46 }
47}
48
49sk_sp<SkSurface> wrap_buffer(GrDirectContext* dContext,
50 Recorder* recorder,
52#if defined(SK_GANESH)
53 if (dContext) {
55 buffer,
57 /* colorSpace= */ nullptr,
58 /* surfaceProps= */ nullptr);
59 }
60#endif
61
62#if defined(SK_GRAPHITE)
63 if (recorder) {
65 buffer,
66 /* colorSpace= */ nullptr,
67 /* surfaceProps= */ nullptr);
68 }
69#endif
70
71 return nullptr;
72}
73
74sk_sp<SkSurface> create_protected_render_target(GrDirectContext* dContext,
75 Recorder* recorder,
76 const SkImageInfo& ii) {
77#if defined(SK_GANESH)
78 if (dContext) {
79 return SkSurfaces::RenderTarget(dContext,
81 ii,
82 /* sampleCount= */ 1,
84 /* surfaceProps= */ nullptr,
85 /* shouldCreateWithMips= */ false,
86 /* isProtected= */ true);
87 }
88#endif
89
90#if defined(SK_GRAPHITE)
91 if (recorder) {
92 // Protected-ness is pulled off of the recorder
93 return SkSurfaces::RenderTarget(recorder,
94 ii,
95 skgpu::Mipmapped::kNo,
96 /* props= */ nullptr);
97 }
98#endif
99
100 return nullptr;
101}
102
103AHardwareBuffer* create_protected_buffer(int width, int height) {
104
105 AHardwareBuffer* buffer = nullptr;
106
107 AHardwareBuffer_Desc hwbDesc;
108 hwbDesc.width = width;
109 hwbDesc.height = height;
110 hwbDesc.layers = 1;
111 hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
112 AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
113 AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
114 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
115
116 hwbDesc.usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
117
118 hwbDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
119 // The following three are not used in the allocate
120 hwbDesc.stride = 0;
121 hwbDesc.rfu0= 0;
122 hwbDesc.rfu1= 0;
123
124 if (int error = AHardwareBuffer_allocate(&hwbDesc, &buffer)) {
125 SkDebugf("Failed to allocated hardware buffer, error: %d\n", error);
126 release_buffer(buffer);
127 return nullptr;
128 }
129
130 return buffer;
131}
132
133sk_sp<SkImage> create_protected_AHB_image(GrDirectContext* dContext,
134 Recorder* recorder,
136 SkColor color) {
137
138 sk_sp<SkSurface> surf = wrap_buffer(dContext, recorder, buffer);
139 if (!surf) {
140 SkDebugf("Failed to make SkSurface.\n");
141 return nullptr;
142 }
143
145
146 return surf->makeImageSnapshot();
147}
148
149sk_sp<SkImage> create_protected_skia_image(GrDirectContext* dContext,
150 Recorder* recorder,
151 int width, int height,
152 SkColor color) {
155
156 sk_sp<SkSurface> tmpSurface = create_protected_render_target(dContext, recorder, ii);
157 if (!tmpSurface) {
158 return nullptr;
159 }
160
161 ToolUtils::draw_checkerboard(tmpSurface->getCanvas(), color, SK_ColorTRANSPARENT, 32);
162
163 return tmpSurface->makeImageSnapshot();
164}
165
166} // anonymous namespace
167
168class ProtectedSlide : public Slide {
169public:
170 ProtectedSlide() { fName = "Protected"; }
171
172 SkISize getDimensions() const override { return {kSize, 2*kSize}; }
173
174 void draw(SkCanvas* origCanvas) override {
175 origCanvas->clear(SK_ColorDKGRAY);
176
177 skgpu::graphite::Recorder* recorder = origCanvas->recorder();
178 GrDirectContext* dContext = GrAsDirectContext(origCanvas->recordingContext());
179
180#if defined(SK_GANESH)
181 if (dContext && !dContext->supportsProtectedContent()) {
182 origCanvas->clear(SK_ColorGREEN);
183 return;
184 }
185#endif
186
187#if defined(SK_GRAPHITE)
188 if (recorder && recorder->priv().isProtected() == skgpu::Protected::kNo) {
189 origCanvas->clear(SK_ColorBLUE);
190 return;
191 }
192#endif
193
194 if (!dContext && !recorder) {
195 origCanvas->clear(SK_ColorRED);
196 return;
197 }
198
199 AHardwareBuffer* buffer = create_protected_buffer(kSize, kSize);
200
201 sk_sp<SkImage> protectedAHBImage = create_protected_AHB_image(dContext, recorder, buffer,
203 sk_sp<SkImage> protectedSkImage = create_protected_skia_image(dContext, recorder,
205
206 // Pick one of the two protected images to draw. Only the protected AHB-backed image will
207 // reproduce the bug (b/242266174).
208 SkImage* imgToUse = protectedAHBImage.get();
209// SkImage* imgToUse = protectedSkImage.get();
210
211 sk_sp<SkImage> indirectImg;
212
213 {
216 sk_sp<SkSurface> tmpS = create_protected_render_target(dContext, recorder, ii);
217
218 tmpS->getCanvas()->clear(SK_ColorMAGENTA);
219 tmpS->getCanvas()->drawCircle(64, 64, 32, SkPaint());
220
221 // For protected AHB-backed images this draw seems to poison all above the draws too
222 tmpS->getCanvas()->drawImage(imgToUse, 0, 0);
223 indirectImg = tmpS->makeImageSnapshot();
224 }
225
226 origCanvas->drawImage(imgToUse, 0, 0);
227 origCanvas->drawImage(indirectImg, 0, kSize);
228
229 protectedAHBImage.reset();
230 protectedSkImage.reset();
231 release_buffer(buffer);
232 }
233
234private:
235 static const int kSize = 128;
236};
237
238DEF_SLIDE( return new ProtectedSlide(); )
239
240#endif
const char * fName
struct AHardwareBuffer AHardwareBuffer
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
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
constexpr SkColor SK_ColorMAGENTA
Definition SkColor.h:147
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorTRANSPARENT
Definition SkColor.h:99
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
constexpr SkColor SK_ColorDKGRAY
Definition SkColor.h:108
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define DEF_SLIDE(code)
Definition Slide.h:25
SK_API bool supportsProtectedContent() const
virtual GrRecordingContext * recordingContext() const
virtual skgpu::graphite::Recorder * recorder() const
void clear(SkColor color)
Definition SkCanvas.h:1199
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
Definition Slide.h:29
virtual SkISize getDimensions() const
Definition Slide.h:35
virtual void draw(SkCanvas *canvas)=0
T * get() const
Definition SkRefCnt.h:303
void reset(T *ptr=nullptr)
Definition SkRefCnt.h:310
Protected isProtected() const
static constexpr int kSize
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
SK_API sk_sp< SkSurface > WrapAndroidHardwareBuffer(skgpu::graphite::Recorder *recorder, AHardwareBuffer *hardwareBuffer, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, BufferReleaseProc=nullptr, ReleaseContext=nullptr, bool fromWindow=false)
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)
void draw_checkerboard(SkCanvas *canvas, SkColor c1, SkColor c2, int size)
int32_t height
int32_t width
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)