1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26 11cb93a386Sopenharmony_ci#define GL_GLEXT_PROTOTYPES 12cb93a386Sopenharmony_ci#define EGL_EGLEXT_PROTOTYPES 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci#include "src/gpu/GrAHardwareBufferImageGenerator.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ci#include <android/hardware_buffer.h> 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h" 20cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 21cb93a386Sopenharmony_ci#include "include/gpu/GrRecordingContext.h" 22cb93a386Sopenharmony_ci#include "include/gpu/gl/GrGLTypes.h" 23cb93a386Sopenharmony_ci#include "src/core/SkMessageBus.h" 24cb93a386Sopenharmony_ci#include "src/gpu/GrAHardwareBufferUtils.h" 25cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 26cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 27cb93a386Sopenharmony_ci#include "src/gpu/GrRecordingContextPriv.h" 28cb93a386Sopenharmony_ci#include "src/gpu/GrResourceCache.h" 29cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 30cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProviderPriv.h" 31cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 32cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxy.h" 33cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h" 34cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLDefines.h" 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci#include <EGL/egl.h> 37cb93a386Sopenharmony_ci#include <EGL/eglext.h> 38cb93a386Sopenharmony_ci#include <GLES/gl.h> 39cb93a386Sopenharmony_ci#include <GLES/glext.h> 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci#ifdef SK_VULKAN 42cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkExtensions.h" 43cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h" 44cb93a386Sopenharmony_ci#endif 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci#define PROT_CONTENT_EXT_STR "EGL_EXT_protected_content" 47cb93a386Sopenharmony_ci#define EGL_PROTECTED_CONTENT_EXT 0x32C0 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_cistd::unique_ptr<SkImageGenerator> GrAHardwareBufferImageGenerator::Make( 50cb93a386Sopenharmony_ci AHardwareBuffer* graphicBuffer, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace, 51cb93a386Sopenharmony_ci GrSurfaceOrigin surfaceOrigin) { 52cb93a386Sopenharmony_ci AHardwareBuffer_Desc bufferDesc; 53cb93a386Sopenharmony_ci AHardwareBuffer_describe(graphicBuffer, &bufferDesc); 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci SkColorType colorType = 56cb93a386Sopenharmony_ci GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format); 57cb93a386Sopenharmony_ci SkImageInfo info = SkImageInfo::Make(bufferDesc.width, bufferDesc.height, colorType, 58cb93a386Sopenharmony_ci alphaType, std::move(colorSpace)); 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci bool createProtectedImage = 0 != (bufferDesc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT); 61cb93a386Sopenharmony_ci return std::unique_ptr<SkImageGenerator>(new GrAHardwareBufferImageGenerator( 62cb93a386Sopenharmony_ci info, graphicBuffer, alphaType, createProtectedImage, 63cb93a386Sopenharmony_ci bufferDesc.format, surfaceOrigin)); 64cb93a386Sopenharmony_ci} 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ciGrAHardwareBufferImageGenerator::GrAHardwareBufferImageGenerator(const SkImageInfo& info, 67cb93a386Sopenharmony_ci AHardwareBuffer* hardwareBuffer, SkAlphaType alphaType, bool isProtectedContent, 68cb93a386Sopenharmony_ci uint32_t bufferFormat, GrSurfaceOrigin surfaceOrigin) 69cb93a386Sopenharmony_ci : INHERITED(info) 70cb93a386Sopenharmony_ci , fHardwareBuffer(hardwareBuffer) 71cb93a386Sopenharmony_ci , fBufferFormat(bufferFormat) 72cb93a386Sopenharmony_ci , fIsProtectedContent(isProtectedContent) 73cb93a386Sopenharmony_ci , fSurfaceOrigin(surfaceOrigin) { 74cb93a386Sopenharmony_ci AHardwareBuffer_acquire(fHardwareBuffer); 75cb93a386Sopenharmony_ci} 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ciGrAHardwareBufferImageGenerator::~GrAHardwareBufferImageGenerator() { 78cb93a386Sopenharmony_ci AHardwareBuffer_release(fHardwareBuffer); 79cb93a386Sopenharmony_ci} 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////////////////////////// 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ciGrSurfaceProxyView GrAHardwareBufferImageGenerator::makeView(GrRecordingContext* context) { 84cb93a386Sopenharmony_ci if (context->abandoned()) { 85cb93a386Sopenharmony_ci return {}; 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ci auto direct = context->asDirectContext(); 89cb93a386Sopenharmony_ci if (!direct) { 90cb93a386Sopenharmony_ci return {}; 91cb93a386Sopenharmony_ci } 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(direct, 94cb93a386Sopenharmony_ci fHardwareBuffer, 95cb93a386Sopenharmony_ci fBufferFormat, 96cb93a386Sopenharmony_ci false); 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ci GrColorType grColorType = SkColorTypeToGrColorType(this->getInfo().colorType()); 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci int width = this->getInfo().width(); 101cb93a386Sopenharmony_ci int height = this->getInfo().height(); 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci auto proxyProvider = context->priv().proxyProvider(); 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci AHardwareBuffer* hardwareBuffer = fHardwareBuffer; 106cb93a386Sopenharmony_ci AHardwareBuffer_acquire(hardwareBuffer); 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci class AutoAHBRelease { 109cb93a386Sopenharmony_ci public: 110cb93a386Sopenharmony_ci AutoAHBRelease(AHardwareBuffer* ahb) : fAhb(ahb) {} 111cb93a386Sopenharmony_ci // std::function() must be CopyConstructible, but ours should never actually be copied. 112cb93a386Sopenharmony_ci AutoAHBRelease(const AutoAHBRelease&) { SkASSERT(0); } 113cb93a386Sopenharmony_ci AutoAHBRelease(AutoAHBRelease&& that) : fAhb(that.fAhb) { that.fAhb = nullptr; } 114cb93a386Sopenharmony_ci ~AutoAHBRelease() { fAhb ? AHardwareBuffer_release(fAhb) : void(); } 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci AutoAHBRelease& operator=(AutoAHBRelease&& that) { 117cb93a386Sopenharmony_ci fAhb = std::exchange(that.fAhb, nullptr); 118cb93a386Sopenharmony_ci return *this; 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci AutoAHBRelease& operator=(const AutoAHBRelease&) = delete; 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci AHardwareBuffer* get() const { return fAhb; } 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci private: 125cb93a386Sopenharmony_ci AHardwareBuffer* fAhb; 126cb93a386Sopenharmony_ci }; 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci sk_sp<GrTextureProxy> texProxy = proxyProvider->createLazyProxy( 129cb93a386Sopenharmony_ci [direct, buffer = AutoAHBRelease(hardwareBuffer)]( 130cb93a386Sopenharmony_ci GrResourceProvider* resourceProvider, 131cb93a386Sopenharmony_ci const GrSurfaceProxy::LazySurfaceDesc& desc) 132cb93a386Sopenharmony_ci -> GrSurfaceProxy::LazyCallbackResult { 133cb93a386Sopenharmony_ci GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr; 134cb93a386Sopenharmony_ci GrAHardwareBufferUtils::UpdateImageProc updateImageProc = nullptr; 135cb93a386Sopenharmony_ci GrAHardwareBufferUtils::TexImageCtx texImageCtx = nullptr; 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci bool isProtected = desc.fProtected == GrProtected::kYes; 138cb93a386Sopenharmony_ci GrBackendTexture backendTex = 139cb93a386Sopenharmony_ci GrAHardwareBufferUtils::MakeBackendTexture(direct, 140cb93a386Sopenharmony_ci buffer.get(), 141cb93a386Sopenharmony_ci desc.fDimensions.width(), 142cb93a386Sopenharmony_ci desc.fDimensions.height(), 143cb93a386Sopenharmony_ci &deleteImageProc, 144cb93a386Sopenharmony_ci &updateImageProc, 145cb93a386Sopenharmony_ci &texImageCtx, 146cb93a386Sopenharmony_ci isProtected, 147cb93a386Sopenharmony_ci desc.fFormat, 148cb93a386Sopenharmony_ci false); 149cb93a386Sopenharmony_ci if (!backendTex.isValid()) { 150cb93a386Sopenharmony_ci return {}; 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci SkASSERT(deleteImageProc && texImageCtx); 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ci // We make this texture cacheable to avoid recreating a GrTexture every time this 155cb93a386Sopenharmony_ci // is invoked. We know the owning SkImage will send an invalidation message when the 156cb93a386Sopenharmony_ci // image is destroyed, so the texture will be removed at that time. Note that the 157cb93a386Sopenharmony_ci // proxy will be keyed in GrProxyProvider but that cache just allows extant proxies 158cb93a386Sopenharmony_ci // to be reused. It does not retain them. After a flush the proxy will be deleted 159cb93a386Sopenharmony_ci // and a subsequent use of the image will recreate a new proxy around the GrTexture 160cb93a386Sopenharmony_ci // found in the GrResourceCache. 161cb93a386Sopenharmony_ci // This is the last use of GrWrapCacheable::kYes so if we actually cached the proxy 162cb93a386Sopenharmony_ci // we could remove wrapped GrGpuResource caching. 163cb93a386Sopenharmony_ci sk_sp<GrTexture> tex = resourceProvider->wrapBackendTexture( 164cb93a386Sopenharmony_ci backendTex, kBorrow_GrWrapOwnership, GrWrapCacheable::kYes, kRead_GrIOType); 165cb93a386Sopenharmony_ci if (!tex) { 166cb93a386Sopenharmony_ci deleteImageProc(texImageCtx); 167cb93a386Sopenharmony_ci return {}; 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci if (deleteImageProc) { 171cb93a386Sopenharmony_ci tex->setRelease(deleteImageProc, texImageCtx); 172cb93a386Sopenharmony_ci } 173cb93a386Sopenharmony_ci 174cb93a386Sopenharmony_ci return tex; 175cb93a386Sopenharmony_ci }, 176cb93a386Sopenharmony_ci backendFormat, {width, height}, GrMipmapped::kNo, GrMipmapStatus::kNotAllocated, 177cb93a386Sopenharmony_ci GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo, 178cb93a386Sopenharmony_ci GrProtected(fIsProtectedContent), GrSurfaceProxy::UseAllocator::kYes); 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci GrSwizzle readSwizzle = context->priv().caps()->getReadSwizzle(backendFormat, grColorType); 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci return GrSurfaceProxyView(std::move(texProxy), fSurfaceOrigin, readSwizzle); 183cb93a386Sopenharmony_ci} 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ciGrSurfaceProxyView GrAHardwareBufferImageGenerator::onGenerateTexture( 186cb93a386Sopenharmony_ci GrRecordingContext* context, 187cb93a386Sopenharmony_ci const SkImageInfo& info, 188cb93a386Sopenharmony_ci const SkIPoint& origin, 189cb93a386Sopenharmony_ci GrMipmapped mipMapped, 190cb93a386Sopenharmony_ci GrImageTexGenPolicy texGenPolicy) { 191cb93a386Sopenharmony_ci GrSurfaceProxyView texProxyView = this->makeView(context); 192cb93a386Sopenharmony_ci if (!texProxyView.proxy()) { 193cb93a386Sopenharmony_ci return {}; 194cb93a386Sopenharmony_ci } 195cb93a386Sopenharmony_ci SkASSERT(texProxyView.asTextureProxy()); 196cb93a386Sopenharmony_ci 197cb93a386Sopenharmony_ci if (texGenPolicy == GrImageTexGenPolicy::kDraw && origin.isZero() && 198cb93a386Sopenharmony_ci info.dimensions() == this->getInfo().dimensions() && mipMapped == GrMipmapped::kNo) { 199cb93a386Sopenharmony_ci // If the caller wants the full non-MIP mapped texture we're done. 200cb93a386Sopenharmony_ci return texProxyView; 201cb93a386Sopenharmony_ci } 202cb93a386Sopenharmony_ci // Otherwise, make a copy for the requested subset and/or MIP maps. 203cb93a386Sopenharmony_ci SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height()); 204cb93a386Sopenharmony_ci 205cb93a386Sopenharmony_ci SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted 206cb93a386Sopenharmony_ci ? SkBudgeted::kNo 207cb93a386Sopenharmony_ci : SkBudgeted::kYes; 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci return GrSurfaceProxyView::Copy(context, std::move(texProxyView), mipMapped, subset, 210cb93a386Sopenharmony_ci SkBackingFit::kExact, budgeted); 211cb93a386Sopenharmony_ci} 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_cibool GrAHardwareBufferImageGenerator::onIsValid(GrRecordingContext* context) const { 214cb93a386Sopenharmony_ci if (nullptr == context) { 215cb93a386Sopenharmony_ci return false; //CPU backend is not supported, because hardware buffer can be swizzled 216cb93a386Sopenharmony_ci } 217cb93a386Sopenharmony_ci return GrBackendApi::kOpenGL == context->backend() || 218cb93a386Sopenharmony_ci GrBackendApi::kVulkan == context->backend(); 219cb93a386Sopenharmony_ci} 220cb93a386Sopenharmony_ci 221cb93a386Sopenharmony_ci#endif //SK_BUILD_FOR_ANDROID_FRAMEWORK 222