GrAHardwareBufferImageGenerator.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright 2017 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. #include "include/core/SkTypes.h"
  8. #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
  9. #define GL_GLEXT_PROTOTYPES
  10. #define EGL_EGLEXT_PROTOTYPES
  11. #include "src/gpu/GrAHardwareBufferImageGenerator.h"
  12. #include <android/hardware_buffer.h>
  13. #include "include/gpu/GrBackendSurface.h"
  14. #include "include/gpu/GrContext.h"
  15. #include "include/gpu/GrTexture.h"
  16. #include "include/gpu/gl/GrGLTypes.h"
  17. #include "include/private/GrRecordingContext.h"
  18. #include "src/core/SkExchange.h"
  19. #include "src/core/SkMessageBus.h"
  20. #include "src/gpu/GrAHardwareBufferUtils.h"
  21. #include "src/gpu/GrContextPriv.h"
  22. #include "src/gpu/GrProxyProvider.h"
  23. #include "src/gpu/GrRecordingContextPriv.h"
  24. #include "src/gpu/GrResourceCache.h"
  25. #include "src/gpu/GrResourceProvider.h"
  26. #include "src/gpu/GrResourceProviderPriv.h"
  27. #include "src/gpu/GrTextureProxy.h"
  28. #include "src/gpu/gl/GrGLDefines.h"
  29. #include <EGL/egl.h>
  30. #include <EGL/eglext.h>
  31. #include <GLES/gl.h>
  32. #include <GLES/glext.h>
  33. #ifdef SK_VULKAN
  34. #include "include/gpu/vk/GrVkExtensions.h"
  35. #include "src/gpu/vk/GrVkGpu.h"
  36. #endif
  37. #define PROT_CONTENT_EXT_STR "EGL_EXT_protected_content"
  38. #define EGL_PROTECTED_CONTENT_EXT 0x32C0
  39. std::unique_ptr<SkImageGenerator> GrAHardwareBufferImageGenerator::Make(
  40. AHardwareBuffer* graphicBuffer, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace,
  41. GrSurfaceOrigin surfaceOrigin) {
  42. AHardwareBuffer_Desc bufferDesc;
  43. AHardwareBuffer_describe(graphicBuffer, &bufferDesc);
  44. SkColorType colorType =
  45. GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format);
  46. SkImageInfo info = SkImageInfo::Make(bufferDesc.width, bufferDesc.height, colorType,
  47. alphaType, std::move(colorSpace));
  48. bool createProtectedImage = 0 != (bufferDesc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
  49. return std::unique_ptr<SkImageGenerator>(new GrAHardwareBufferImageGenerator(
  50. info, graphicBuffer, alphaType, createProtectedImage,
  51. bufferDesc.format, surfaceOrigin));
  52. }
  53. GrAHardwareBufferImageGenerator::GrAHardwareBufferImageGenerator(const SkImageInfo& info,
  54. AHardwareBuffer* hardwareBuffer, SkAlphaType alphaType, bool isProtectedContent,
  55. uint32_t bufferFormat, GrSurfaceOrigin surfaceOrigin)
  56. : INHERITED(info)
  57. , fHardwareBuffer(hardwareBuffer)
  58. , fBufferFormat(bufferFormat)
  59. , fIsProtectedContent(isProtectedContent)
  60. , fSurfaceOrigin(surfaceOrigin) {
  61. AHardwareBuffer_acquire(fHardwareBuffer);
  62. }
  63. GrAHardwareBufferImageGenerator::~GrAHardwareBufferImageGenerator() {
  64. AHardwareBuffer_release(fHardwareBuffer);
  65. }
  66. ///////////////////////////////////////////////////////////////////////////////////////////////////
  67. sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::makeProxy(GrRecordingContext* context) {
  68. if (context->priv().abandoned()) {
  69. return nullptr;
  70. }
  71. auto direct = context->priv().asDirectContext();
  72. if (!direct) {
  73. return nullptr;
  74. }
  75. GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(direct,
  76. fHardwareBuffer,
  77. fBufferFormat,
  78. false);
  79. GrColorType grColorType = SkColorTypeToGrColorType(this->getInfo().colorType());
  80. GrPixelConfig pixelConfig = context->priv().caps()->getConfigFromBackendFormat(backendFormat,
  81. grColorType);
  82. if (pixelConfig == kUnknown_GrPixelConfig) {
  83. return nullptr;
  84. }
  85. int width = this->getInfo().width();
  86. int height = this->getInfo().height();
  87. GrSurfaceDesc desc;
  88. desc.fWidth = width;
  89. desc.fHeight = height;
  90. desc.fConfig = pixelConfig;
  91. GrTextureType textureType = GrTextureType::k2D;
  92. if (context->backend() == GrBackendApi::kOpenGL) {
  93. textureType = GrTextureType::kExternal;
  94. } else if (context->backend() == GrBackendApi::kVulkan) {
  95. const VkFormat* format = backendFormat.getVkFormat();
  96. SkASSERT(format);
  97. if (*format == VK_FORMAT_UNDEFINED) {
  98. textureType = GrTextureType::kExternal;
  99. }
  100. }
  101. auto proxyProvider = context->priv().proxyProvider();
  102. AHardwareBuffer* hardwareBuffer = fHardwareBuffer;
  103. AHardwareBuffer_acquire(hardwareBuffer);
  104. const bool isProtectedContent = fIsProtectedContent;
  105. class AutoAHBRelease {
  106. public:
  107. AutoAHBRelease(AHardwareBuffer* ahb) : fAhb(ahb) {}
  108. // std::function() must be CopyConstructible, but ours should never actually be copied.
  109. AutoAHBRelease(const AutoAHBRelease&) { SkASSERT(0); }
  110. AutoAHBRelease(AutoAHBRelease&& that) : fAhb(that.fAhb) { that.fAhb = nullptr; }
  111. ~AutoAHBRelease() { fAhb ? AHardwareBuffer_release(fAhb) : void(); }
  112. AutoAHBRelease& operator=(AutoAHBRelease&& that) {
  113. fAhb = skstd::exchange(that.fAhb, nullptr);
  114. return *this;
  115. }
  116. AutoAHBRelease& operator=(const AutoAHBRelease&) = delete;
  117. AHardwareBuffer* get() const { return fAhb; }
  118. private:
  119. AHardwareBuffer* fAhb;
  120. };
  121. sk_sp<GrTextureProxy> texProxy = proxyProvider->createLazyProxy(
  122. [direct, buffer = AutoAHBRelease(hardwareBuffer), width, height, pixelConfig,
  123. isProtectedContent, backendFormat, grColorType](GrResourceProvider* resourceProvider)
  124. -> GrSurfaceProxy::LazyInstantiationResult {
  125. GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr;
  126. GrAHardwareBufferUtils::DeleteImageCtx deleteImageCtx = nullptr;
  127. GrBackendTexture backendTex =
  128. GrAHardwareBufferUtils::MakeBackendTexture(direct, buffer.get(),
  129. width, height,
  130. &deleteImageProc,
  131. &deleteImageCtx,
  132. isProtectedContent,
  133. backendFormat,
  134. false);
  135. if (!backendTex.isValid()) {
  136. return {};
  137. }
  138. SkASSERT(deleteImageProc && deleteImageCtx);
  139. backendTex.fConfig = pixelConfig;
  140. // We make this texture cacheable to avoid recreating a GrTexture every time this
  141. // is invoked. We know the owning SkIamge will send an invalidation message when the
  142. // image is destroyed, so the texture will be removed at that time.
  143. sk_sp<GrTexture> tex = resourceProvider->wrapBackendTexture(
  144. backendTex, grColorType, kBorrow_GrWrapOwnership, GrWrapCacheable::kYes,
  145. kRead_GrIOType);
  146. if (!tex) {
  147. deleteImageProc(deleteImageCtx);
  148. return {};
  149. }
  150. if (deleteImageProc) {
  151. tex->setRelease(deleteImageProc, deleteImageCtx);
  152. }
  153. return std::move(tex);
  154. },
  155. backendFormat, desc, GrRenderable::kNo, 1, fSurfaceOrigin, GrMipMapped::kNo,
  156. GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
  157. GrProtected::kNo);
  158. return texProxy;
  159. }
  160. sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::onGenerateTexture(
  161. GrRecordingContext* context, const SkImageInfo& info,
  162. const SkIPoint& origin, bool willNeedMipMaps) {
  163. sk_sp<GrTextureProxy> texProxy = this->makeProxy(context);
  164. if (!texProxy) {
  165. return nullptr;
  166. }
  167. if (0 == origin.fX && 0 == origin.fY &&
  168. info.width() == this->getInfo().width() && info.height() == this->getInfo().height()) {
  169. // If the caller wants the full texture we're done. The caller will handle making a copy for
  170. // mip maps if that is required.
  171. return texProxy;
  172. }
  173. // Otherwise, make a copy for the requested subset.
  174. SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height());
  175. GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
  176. return GrSurfaceProxy::Copy(context, texProxy.get(), mipMapped, subset, SkBackingFit::kExact,
  177. SkBudgeted::kYes);
  178. }
  179. bool GrAHardwareBufferImageGenerator::onIsValid(GrContext* context) const {
  180. if (nullptr == context) {
  181. return false; //CPU backend is not supported, because hardware buffer can be swizzled
  182. }
  183. return GrBackendApi::kOpenGL == context->backend() ||
  184. GrBackendApi::kVulkan == context->backend();
  185. }
  186. #endif //SK_BUILD_FOR_ANDROID_FRAMEWORK