Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
AHardwareBufferTest.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 __ANDROID_API__ >= 26
11
22#include "tests/Test.h"
23
25
26using namespace skgpu::graphite;
27
28static const int DEV_W = 16, DEV_H = 16;
29
30namespace {
31
32SkPMColor get_src_color(int x, int y) {
33 SkASSERT(x >= 0 && x < DEV_W);
34 SkASSERT(y >= 0 && y < DEV_H);
35
36 U8CPU r = x;
37 U8CPU g = y;
38 U8CPU b = 0xc;
39
40 U8CPU a = 0xff;
41 switch ((x+y) % 5) {
42 case 0:
43 a = 0xff;
44 break;
45 case 1:
46 a = 0x80;
47 break;
48 case 2:
49 a = 0xCC;
50 break;
51 case 4:
52 a = 0x01;
53 break;
54 case 3:
55 a = 0x00;
56 break;
57 }
58 a = 0xff;
59 return SkPremultiplyARGBInline(a, r, g, b);
60}
61
62SkBitmap make_src_bitmap() {
63 static SkBitmap bmp;
64 if (bmp.isNull()) {
66 intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels());
67 for (int y = 0; y < DEV_H; ++y) {
68 for (int x = 0; x < DEV_W; ++x) {
69 SkPMColor* pixel = reinterpret_cast<SkPMColor*>(
70 pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel());
71 *pixel = get_src_color(x, y);
72 }
73 }
74 }
75 return bmp;
76}
77
78bool check_read(skiatest::Reporter* reporter, const SkBitmap& expectedBitmap,
79 const SkBitmap& actualBitmap) {
80 bool result = true;
81 for (int y = 0; y < DEV_H && result; ++y) {
82 for (int x = 0; x < DEV_W && result; ++x) {
83 const uint32_t srcPixel = *expectedBitmap.getAddr32(x, y);
84 const uint32_t dstPixel = *actualBitmap.getAddr32(x, y);
85 if (srcPixel != dstPixel) {
86 ERRORF(reporter, "Expected readback pixel (%d, %d) value 0x%08x, got 0x%08x.",
87 x, y, srcPixel, dstPixel);
88 result = false;
89 }/* else {
90 SkDebugf("Got good pixel (%d, %d) value 0x%08x, got 0x%08x.\n",
91 x, y, srcPixel, dstPixel);
92 }*/
93 }
94 }
95 return result;
96}
97
99 int width, int height,
100 bool forSurface, bool isProtected,
101 const SkBitmap* data) {
102
103 AHardwareBuffer_Desc hwbDesc;
104 hwbDesc.width = width;
105 hwbDesc.height = height;
106 hwbDesc.layers = 1;
107 hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
108 AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
109 (isProtected ? AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT : 0);
110
111 if (forSurface) {
112 SkASSERT(!data);
113 hwbDesc.usage |= AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
114 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
115 } else {
116 hwbDesc.usage |= AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
117 }
118
119 hwbDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
120 // The following three are not used by AHardwareBuffer_allocate
121 hwbDesc.stride = 0;
122 hwbDesc.rfu0= 0;
123 hwbDesc.rfu1= 0;
124
125 AHardwareBuffer* buffer = nullptr;
126 if (int error = AHardwareBuffer_allocate(&hwbDesc, &buffer)) {
127 ERRORF(reporter, "Failed to allocated hardware buffer, error: %d", error);
128 return nullptr;
129 }
130
131 if (data) {
132 SkASSERT(data->width() == width && data->height() == height);
133 // Get actual desc for allocated buffer so we know the stride for uploading cpu data.
134 AHardwareBuffer_describe(buffer, &hwbDesc);
135
136 uint32_t* bufferAddr;
137 if (AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, nullptr,
138 reinterpret_cast<void**>(&bufferAddr))) {
139 ERRORF(reporter, "Failed to lock hardware buffer");
140 AHardwareBuffer_release(buffer);
141 return nullptr;
142 }
143
144 int bbp = data->bytesPerPixel();
145 uint32_t* src = (uint32_t*)data->getPixels();
146 int nextLineStep = width;
147 uint32_t* dst = bufferAddr;
148 for (int y = 0; y < height; ++y) {
149 memcpy(dst, src, width * bbp);
150 src += nextLineStep;
151 dst += hwbDesc.stride;
152 }
153 AHardwareBuffer_unlock(buffer, nullptr);
154 }
155
156 return buffer;
157}
158
159void delete_buffer(void* context) {
160 AHardwareBuffer* buffer = static_cast<AHardwareBuffer*>(context);
161 if (buffer) {
162 AHardwareBuffer_release(buffer);
163 }
164}
165
166} // anonymous namespace
167
168// Test to make sure we can import an AHardwareBuffer into an SkSurface and draw into it.
169DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(Graphite_AHardwareBuffer_ImportAsSurface,
170 reporter,
171 context,
173 if (!context->priv().caps()->supportsAHardwareBufferImages()) {
174 return;
175 }
176
177 bool isProtected = context->priv().caps()->protectedSupport();
178
179 std::unique_ptr<Recorder> recorder = context->makeRecorder();
180
181 ///////////////////////////////////////////////////////////////////////////
182 // Setup SkBitmaps
183 ///////////////////////////////////////////////////////////////////////////
184
185 const SkBitmap srcBitmap = make_src_bitmap();
186
187 AHardwareBuffer* buffer = create_AHB(reporter,
188 DEV_W, DEV_H,
189 /* writeable= */ true,
190 isProtected,
191 /* data= */ nullptr);
192 if (!buffer) {
193 return;
194 }
195
197 buffer,
198 /* colorSpace= */ nullptr,
199 /* surfaceProps= */ nullptr,
200 delete_buffer,
201 buffer);
202 if (!surface) {
203 ERRORF(reporter, "Failed to make SkSurface.");
204 return;
205 }
206
207 sk_sp<SkImage> grBacked = SkImages::TextureFromImage(recorder.get(), srcBitmap.asImage().get());
208
209 surface->getCanvas()->drawImage(grBacked, 0, 0);
210
211 if (!isProtected) {
212 // In Protected mode we can't readback so we just test that we can wrap the AHB and
213 // draw it w/o errors
214 SkBitmap readbackBitmap;
215 readbackBitmap.allocN32Pixels(DEV_W, DEV_H);
216
217 REPORTER_ASSERT(reporter, surface->readPixels(readbackBitmap, 0, 0));
218 REPORTER_ASSERT(reporter, check_read(reporter, srcBitmap, readbackBitmap));
219 }
220
221 surface.reset();
222}
223
224#endif // __ANDROID_API__ >= 26
static const int DEV_H
static const int DEV_W
reporter
struct AHardwareBuffer AHardwareBuffer
static bool check_read(skiatest::Reporter *reporter, const SkBitmap &bitmap)
static SkPMColor get_src_color(int x, int y)
#define SkASSERT(cond)
Definition SkAssert.h:116
unsigned U8CPU
Definition SkCPUTypes.h:18
static SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
uint32_t SkPMColor
Definition SkColor.h:205
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(name, reporter, graphite_context, ctsEnforcement)
Definition Test.h:377
#define ERRORF(r,...)
Definition Test.h:293
sk_sp< SkImage > asImage() const
Definition SkBitmap.cpp:645
size_t rowBytes() const
Definition SkBitmap.h:238
bool isNull() const
Definition SkBitmap.h:219
void * getPixels() const
Definition SkBitmap.h:283
int bytesPerPixel() const
Definition SkBitmap.h:187
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition SkBitmap.cpp:232
uint32_t * getAddr32(int x, int y) const
Definition SkBitmap.h:1260
T * get() const
Definition SkRefCnt.h:303
VkSurfaceKHR surface
Definition main.cc:49
static bool b
struct MyStruct a[10]
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
double y
double x
SK_API sk_sp< SkImage > TextureFromImage(GrDirectContext *, const SkImage *, skgpu::Mipmapped=skgpu::Mipmapped::kNo, skgpu::Budgeted=skgpu::Budgeted::kYes)
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)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
dst
Definition cp.py:12
int32_t height
int32_t width