• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "AutoBackendTextureRelease.h"
18 
19 #include "renderthread/RenderThread.h"
20 #include "utils/Color.h"
21 #include "utils/PaintUtils.h"
22 
23 using namespace android::uirenderer::renderthread;
24 
25 namespace android {
26 namespace uirenderer {
27 
AutoBackendTextureRelease(GrContext * context,AHardwareBuffer * buffer)28 AutoBackendTextureRelease::AutoBackendTextureRelease(GrContext* context, AHardwareBuffer* buffer) {
29     AHardwareBuffer_Desc desc;
30     AHardwareBuffer_describe(buffer, &desc);
31     bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
32     GrBackendFormat backendFormat =
33             GrAHardwareBufferUtils::GetBackendFormat(context, buffer, desc.format, false);
34     mBackendTexture = GrAHardwareBufferUtils::MakeBackendTexture(
35             context, buffer, desc.width, desc.height, &mDeleteProc, &mUpdateProc, &mImageCtx,
36             createProtectedImage, backendFormat, false);
37 }
38 
unref(bool releaseImage)39 void AutoBackendTextureRelease::unref(bool releaseImage) {
40     if (!RenderThread::isCurrent()) {
41         // EGLImage needs to be destroyed on RenderThread to prevent memory leak.
42         // ~SkImage dtor for both pipelines needs to be invoked on RenderThread, because it is not
43         // thread safe.
44         RenderThread::getInstance().queue().post([this, releaseImage]() { unref(releaseImage); });
45         return;
46     }
47 
48     if (releaseImage) {
49         mImage.reset();
50     }
51 
52     mUsageCount--;
53     if (mUsageCount <= 0) {
54         if (mBackendTexture.isValid()) {
55             mDeleteProc(mImageCtx);
56             mBackendTexture = {};
57         }
58         delete this;
59     }
60 }
61 
62 // releaseProc is invoked by SkImage, when texture is no longer in use.
63 // "releaseContext" contains an "AutoBackendTextureRelease*".
releaseProc(SkImage::ReleaseContext releaseContext)64 static void releaseProc(SkImage::ReleaseContext releaseContext) {
65     AutoBackendTextureRelease* textureRelease =
66             reinterpret_cast<AutoBackendTextureRelease*>(releaseContext);
67     textureRelease->unref(false);
68 }
69 
makeImage(AHardwareBuffer * buffer,android_dataspace dataspace,GrContext * context)70 void AutoBackendTextureRelease::makeImage(AHardwareBuffer* buffer, android_dataspace dataspace,
71                                           GrContext* context) {
72     AHardwareBuffer_Desc desc;
73     AHardwareBuffer_describe(buffer, &desc);
74     SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format);
75     mImage = SkImage::MakeFromTexture(
76             context, mBackendTexture, kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType,
77             uirenderer::DataSpaceToColorSpace(dataspace), releaseProc, this);
78     if (mImage.get()) {
79         // The following ref will be counteracted by releaseProc, when SkImage is discarded.
80         ref();
81     }
82 }
83 
newBufferContent(GrContext * context)84 void AutoBackendTextureRelease::newBufferContent(GrContext* context) {
85     if (mBackendTexture.isValid()) {
86         mUpdateProc(mImageCtx, context);
87     }
88 }
89 
90 } /* namespace uirenderer */
91 } /* namespace android */
92