GrAHardwareBufferTest.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * Copyright 2018 Google 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. // This is a GPU-backend specific test. It relies on static intializers to work
  8. #include "include/core/SkTypes.h"
  9. #if SK_SUPPORT_GPU && defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
  10. #include "include/core/SkImage.h"
  11. #include "include/core/SkSurface.h"
  12. #include "include/gpu/GrContext.h"
  13. #include "src/gpu/GrAHardwareBufferImageGenerator.h"
  14. #include "src/gpu/GrContextPriv.h"
  15. #include "src/gpu/GrGpu.h"
  16. #include "tests/Test.h"
  17. #include "tools/gpu/GrContextFactory.h"
  18. #include <android/hardware_buffer.h>
  19. #include <cinttypes>
  20. static const int DEV_W = 16, DEV_H = 16;
  21. static SkPMColor get_src_color(int x, int y) {
  22. SkASSERT(x >= 0 && x < DEV_W);
  23. SkASSERT(y >= 0 && y < DEV_H);
  24. U8CPU r = x;
  25. U8CPU g = y;
  26. U8CPU b = 0xc;
  27. U8CPU a = 0xff;
  28. switch ((x+y) % 5) {
  29. case 0:
  30. a = 0xff;
  31. break;
  32. case 1:
  33. a = 0x80;
  34. break;
  35. case 2:
  36. a = 0xCC;
  37. break;
  38. case 4:
  39. a = 0x01;
  40. break;
  41. case 3:
  42. a = 0x00;
  43. break;
  44. }
  45. a = 0xff;
  46. return SkPremultiplyARGBInline(a, r, g, b);
  47. }
  48. static SkBitmap make_src_bitmap() {
  49. static SkBitmap bmp;
  50. if (bmp.isNull()) {
  51. bmp.allocN32Pixels(DEV_W, DEV_H);
  52. intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels());
  53. for (int y = 0; y < DEV_H; ++y) {
  54. for (int x = 0; x < DEV_W; ++x) {
  55. SkPMColor* pixel = reinterpret_cast<SkPMColor*>(
  56. pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel());
  57. *pixel = get_src_color(x, y);
  58. }
  59. }
  60. }
  61. return bmp;
  62. }
  63. static bool check_read(skiatest::Reporter* reporter, const SkBitmap& expectedBitmap,
  64. const SkBitmap& actualBitmap) {
  65. bool result = true;
  66. for (int y = 0; y < DEV_H && result; ++y) {
  67. for (int x = 0; x < DEV_W && result; ++x) {
  68. const uint32_t srcPixel = *expectedBitmap.getAddr32(x, y);
  69. const uint32_t dstPixel = *actualBitmap.getAddr32(x, y);
  70. if (srcPixel != dstPixel) {
  71. ERRORF(reporter, "Expected readback pixel (%d, %d) value 0x%08x, got 0x%08x.",
  72. x, y, srcPixel, dstPixel);
  73. result = false;
  74. }/* else {
  75. SkDebugf("Got good pixel (%d, %d) value 0x%08x, got 0x%08x.\n",
  76. x, y, srcPixel, dstPixel);
  77. }*/
  78. }
  79. }
  80. return result;
  81. }
  82. static void cleanup_resources(AHardwareBuffer* buffer) {
  83. if (buffer) {
  84. AHardwareBuffer_release(buffer);
  85. }
  86. }
  87. static void basic_draw_test_helper(skiatest::Reporter* reporter,
  88. const sk_gpu_test::ContextInfo& info,
  89. GrSurfaceOrigin surfaceOrigin) {
  90. GrContext* context = info.grContext();
  91. if (!context->priv().caps()->supportsAHardwareBufferImages()) {
  92. return;
  93. }
  94. ///////////////////////////////////////////////////////////////////////////
  95. // Setup SkBitmaps
  96. ///////////////////////////////////////////////////////////////////////////
  97. const SkBitmap srcBitmap = make_src_bitmap();
  98. ///////////////////////////////////////////////////////////////////////////
  99. // Setup AHardwareBuffer
  100. ///////////////////////////////////////////////////////////////////////////
  101. AHardwareBuffer* buffer = nullptr;
  102. AHardwareBuffer_Desc hwbDesc;
  103. hwbDesc.width = DEV_W;
  104. hwbDesc.height = DEV_H;
  105. hwbDesc.layers = 1;
  106. hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
  107. AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
  108. AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
  109. hwbDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
  110. // The following three are not used in the allocate
  111. hwbDesc.stride = 0;
  112. hwbDesc.rfu0= 0;
  113. hwbDesc.rfu1= 0;
  114. if (int error = AHardwareBuffer_allocate(&hwbDesc, &buffer)) {
  115. ERRORF(reporter, "Failed to allocated hardware buffer, error: %d", error);
  116. cleanup_resources(buffer);
  117. return;
  118. }
  119. // Get actual desc for allocated buffer so we know the stride for uploading cpu data.
  120. AHardwareBuffer_describe(buffer, &hwbDesc);
  121. uint32_t* bufferAddr;
  122. if (AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, nullptr,
  123. reinterpret_cast<void**>(&bufferAddr))) {
  124. ERRORF(reporter, "Failed to lock hardware buffer");
  125. cleanup_resources(buffer);
  126. return;
  127. }
  128. int bbp = srcBitmap.bytesPerPixel();
  129. uint32_t* src = (uint32_t*)srcBitmap.getPixels();
  130. int nextLineStep = DEV_W;
  131. if (surfaceOrigin == kBottomLeft_GrSurfaceOrigin) {
  132. nextLineStep = -nextLineStep;
  133. src += (DEV_H-1)*DEV_W;
  134. }
  135. uint32_t* dst = bufferAddr;
  136. for (int y = 0; y < DEV_H; ++y) {
  137. memcpy(dst, src, DEV_W * bbp);
  138. src += nextLineStep;
  139. dst += hwbDesc.stride;
  140. }
  141. AHardwareBuffer_unlock(buffer, nullptr);
  142. ///////////////////////////////////////////////////////////////////////////
  143. // Wrap AHardwareBuffer in SkImage
  144. ///////////////////////////////////////////////////////////////////////////
  145. sk_sp<SkImage> image = SkImage::MakeFromAHardwareBuffer(buffer, kPremul_SkAlphaType,
  146. nullptr, surfaceOrigin);
  147. REPORTER_ASSERT(reporter, image);
  148. ///////////////////////////////////////////////////////////////////////////
  149. // Make a surface to draw into
  150. ///////////////////////////////////////////////////////////////////////////
  151. SkImageInfo imageInfo = SkImageInfo::Make(DEV_W, DEV_H, kRGBA_8888_SkColorType,
  152. kPremul_SkAlphaType);
  153. sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
  154. imageInfo);
  155. REPORTER_ASSERT(reporter, surface);
  156. ///////////////////////////////////////////////////////////////////////////
  157. // Draw the AHardwareBuffer SkImage into surface
  158. ///////////////////////////////////////////////////////////////////////////
  159. surface->getCanvas()->drawImage(image, 0, 0);
  160. SkBitmap readbackBitmap;
  161. readbackBitmap.allocN32Pixels(DEV_W, DEV_H);
  162. REPORTER_ASSERT(reporter, surface->readPixels(readbackBitmap, 0, 0));
  163. REPORTER_ASSERT(reporter, check_read(reporter, srcBitmap, readbackBitmap));
  164. image.reset();
  165. cleanup_resources(buffer);
  166. }
  167. // Basic test to make sure we can import an AHardwareBuffer into an SkImage and draw it into a
  168. // surface.
  169. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrAHardwareBuffer_BasicDrawTest,
  170. reporter, context_info) {
  171. basic_draw_test_helper(reporter, context_info, kTopLeft_GrSurfaceOrigin);
  172. basic_draw_test_helper(reporter, context_info, kBottomLeft_GrSurfaceOrigin);
  173. }
  174. static void surface_draw_test_helper(skiatest::Reporter* reporter,
  175. const sk_gpu_test::ContextInfo& info,
  176. GrSurfaceOrigin surfaceOrigin) {
  177. GrContext* context = info.grContext();
  178. if (!context->priv().caps()->supportsAHardwareBufferImages()) {
  179. return;
  180. }
  181. ///////////////////////////////////////////////////////////////////////////
  182. // Setup SkBitmaps
  183. ///////////////////////////////////////////////////////////////////////////
  184. const SkBitmap srcBitmap = make_src_bitmap();
  185. ///////////////////////////////////////////////////////////////////////////
  186. // Setup AHardwareBuffer
  187. ///////////////////////////////////////////////////////////////////////////
  188. AHardwareBuffer* buffer = nullptr;
  189. AHardwareBuffer_Desc hwbDesc;
  190. hwbDesc.width = DEV_W;
  191. hwbDesc.height = DEV_H;
  192. hwbDesc.layers = 1;
  193. hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
  194. AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
  195. AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
  196. AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
  197. hwbDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
  198. // The following three are not used in the allocate
  199. hwbDesc.stride = 0;
  200. hwbDesc.rfu0= 0;
  201. hwbDesc.rfu1= 0;
  202. if (int error = AHardwareBuffer_allocate(&hwbDesc, &buffer)) {
  203. ERRORF(reporter, "Failed to allocated hardware buffer, error: %d", error);
  204. cleanup_resources(buffer);
  205. return;
  206. }
  207. sk_sp<SkSurface> surface = SkSurface::MakeFromAHardwareBuffer(context, buffer, surfaceOrigin,
  208. nullptr, nullptr);
  209. if (!surface) {
  210. ERRORF(reporter, "Failed to make SkSurface.");
  211. cleanup_resources(buffer);
  212. return;
  213. }
  214. surface->getCanvas()->drawBitmap(srcBitmap, 0, 0);
  215. SkBitmap readbackBitmap;
  216. readbackBitmap.allocN32Pixels(DEV_W, DEV_H);
  217. REPORTER_ASSERT(reporter, surface->readPixels(readbackBitmap, 0, 0));
  218. REPORTER_ASSERT(reporter, check_read(reporter, srcBitmap, readbackBitmap));
  219. cleanup_resources(buffer);
  220. }
  221. // Test to make sure we can import an AHardwareBuffer into an SkSurface and draw into it.
  222. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrAHardwareBuffer_ImportAsSurface,
  223. reporter, context_info) {
  224. surface_draw_test_helper(reporter, context_info, kTopLeft_GrSurfaceOrigin);
  225. surface_draw_test_helper(reporter, context_info, kBottomLeft_GrSurfaceOrigin);
  226. }
  227. #endif