xref: /aosp_15_r20/frameworks/native/libs/renderengine/skia/AutoBackendTexture.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2020 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <SkImage.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <SkSurface.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <include/gpu/ganesh/GrDirectContext.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicTypes.h>
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker #include "android-base/macros.h"
26*38e8c45fSAndroid Build Coastguard Worker #include "compat/SkiaBackendTexture.h"
27*38e8c45fSAndroid Build Coastguard Worker 
28*38e8c45fSAndroid Build Coastguard Worker #include <memory>
29*38e8c45fSAndroid Build Coastguard Worker #include <vector>
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker namespace android {
32*38e8c45fSAndroid Build Coastguard Worker namespace renderengine {
33*38e8c45fSAndroid Build Coastguard Worker namespace skia {
34*38e8c45fSAndroid Build Coastguard Worker 
35*38e8c45fSAndroid Build Coastguard Worker /**
36*38e8c45fSAndroid Build Coastguard Worker  * AutoBackendTexture manages GPU image lifetime. It is a ref-counted object
37*38e8c45fSAndroid Build Coastguard Worker  * that keeps GPU resources alive until the last SkImage or SkSurface object using them is
38*38e8c45fSAndroid Build Coastguard Worker  * destroyed.
39*38e8c45fSAndroid Build Coastguard Worker  */
40*38e8c45fSAndroid Build Coastguard Worker class AutoBackendTexture {
41*38e8c45fSAndroid Build Coastguard Worker public:
42*38e8c45fSAndroid Build Coastguard Worker     // Manager class that is responsible for the immediate or deferred cleanup
43*38e8c45fSAndroid Build Coastguard Worker     // of AutoBackendTextures.  Clients of AutoBackendTexture are responsible for
44*38e8c45fSAndroid Build Coastguard Worker     // ensuring that access to this class is thread safe.  Clients also control when
45*38e8c45fSAndroid Build Coastguard Worker     // the resources are reclaimed by setting the manager into deferred mode.
46*38e8c45fSAndroid Build Coastguard Worker     class CleanupManager {
47*38e8c45fSAndroid Build Coastguard Worker     public:
48*38e8c45fSAndroid Build Coastguard Worker         CleanupManager() = default;
add(AutoBackendTexture * abt)49*38e8c45fSAndroid Build Coastguard Worker         void add(AutoBackendTexture* abt) {
50*38e8c45fSAndroid Build Coastguard Worker             if (mDeferCleanup) {
51*38e8c45fSAndroid Build Coastguard Worker                 mCleanupList.push_back(abt);
52*38e8c45fSAndroid Build Coastguard Worker             } else {
53*38e8c45fSAndroid Build Coastguard Worker                 delete abt;
54*38e8c45fSAndroid Build Coastguard Worker             }
55*38e8c45fSAndroid Build Coastguard Worker         }
56*38e8c45fSAndroid Build Coastguard Worker 
setDeferredStatus(bool enabled)57*38e8c45fSAndroid Build Coastguard Worker         void setDeferredStatus(bool enabled) { mDeferCleanup = enabled; }
58*38e8c45fSAndroid Build Coastguard Worker 
isEmpty()59*38e8c45fSAndroid Build Coastguard Worker         bool isEmpty() const { return mCleanupList.empty(); }
60*38e8c45fSAndroid Build Coastguard Worker 
61*38e8c45fSAndroid Build Coastguard Worker         // If any AutoBackedTextures were added while in deferred mode this method
62*38e8c45fSAndroid Build Coastguard Worker         // will ensure they are deleted before returning.  It must only be called
63*38e8c45fSAndroid Build Coastguard Worker         // on the thread where the GPU context that created the AutoBackedTexture
64*38e8c45fSAndroid Build Coastguard Worker         // is active.
cleanup()65*38e8c45fSAndroid Build Coastguard Worker         void cleanup() {
66*38e8c45fSAndroid Build Coastguard Worker             for (auto abt : mCleanupList) {
67*38e8c45fSAndroid Build Coastguard Worker                 delete abt;
68*38e8c45fSAndroid Build Coastguard Worker             }
69*38e8c45fSAndroid Build Coastguard Worker             mCleanupList.clear();
70*38e8c45fSAndroid Build Coastguard Worker         }
71*38e8c45fSAndroid Build Coastguard Worker 
72*38e8c45fSAndroid Build Coastguard Worker     private:
73*38e8c45fSAndroid Build Coastguard Worker         DISALLOW_COPY_AND_ASSIGN(CleanupManager);
74*38e8c45fSAndroid Build Coastguard Worker         bool mDeferCleanup = false;
75*38e8c45fSAndroid Build Coastguard Worker         std::vector<AutoBackendTexture*> mCleanupList;
76*38e8c45fSAndroid Build Coastguard Worker     };
77*38e8c45fSAndroid Build Coastguard Worker 
78*38e8c45fSAndroid Build Coastguard Worker     // Local reference that supports RAII-style management of an AutoBackendTexture
79*38e8c45fSAndroid Build Coastguard Worker     // AutoBackendTexture by itself can't be managed in a similar fashion because
80*38e8c45fSAndroid Build Coastguard Worker     // of shared ownership with Skia objects, so we wrap it here instead.
81*38e8c45fSAndroid Build Coastguard Worker     class LocalRef {
82*38e8c45fSAndroid Build Coastguard Worker     public:
LocalRef(std::unique_ptr<SkiaBackendTexture> backendTexture,CleanupManager & cleanupMgr)83*38e8c45fSAndroid Build Coastguard Worker         LocalRef(std::unique_ptr<SkiaBackendTexture> backendTexture, CleanupManager& cleanupMgr) {
84*38e8c45fSAndroid Build Coastguard Worker             mTexture = new AutoBackendTexture(std::move(backendTexture), cleanupMgr);
85*38e8c45fSAndroid Build Coastguard Worker             mTexture->ref();
86*38e8c45fSAndroid Build Coastguard Worker         }
87*38e8c45fSAndroid Build Coastguard Worker 
~LocalRef()88*38e8c45fSAndroid Build Coastguard Worker         ~LocalRef() {
89*38e8c45fSAndroid Build Coastguard Worker             if (mTexture != nullptr) {
90*38e8c45fSAndroid Build Coastguard Worker                 mTexture->unref(true);
91*38e8c45fSAndroid Build Coastguard Worker             }
92*38e8c45fSAndroid Build Coastguard Worker         }
93*38e8c45fSAndroid Build Coastguard Worker 
94*38e8c45fSAndroid Build Coastguard Worker         // Makes a new SkImage from the texture content.
95*38e8c45fSAndroid Build Coastguard Worker         // As SkImages are immutable but buffer content is not, we create
96*38e8c45fSAndroid Build Coastguard Worker         // a new SkImage every time.
makeImage(ui::Dataspace dataspace,SkAlphaType alphaType)97*38e8c45fSAndroid Build Coastguard Worker         sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType) {
98*38e8c45fSAndroid Build Coastguard Worker             return mTexture->makeImage(dataspace, alphaType);
99*38e8c45fSAndroid Build Coastguard Worker         }
100*38e8c45fSAndroid Build Coastguard Worker 
101*38e8c45fSAndroid Build Coastguard Worker         // Makes a new SkSurface from the texture content, if needed.
getOrCreateSurface(ui::Dataspace dataspace)102*38e8c45fSAndroid Build Coastguard Worker         sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace) {
103*38e8c45fSAndroid Build Coastguard Worker             return mTexture->getOrCreateSurface(dataspace);
104*38e8c45fSAndroid Build Coastguard Worker         }
105*38e8c45fSAndroid Build Coastguard Worker 
colorType()106*38e8c45fSAndroid Build Coastguard Worker         SkColorType colorType() const { return mTexture->mBackendTexture->internalColorType(); }
107*38e8c45fSAndroid Build Coastguard Worker 
108*38e8c45fSAndroid Build Coastguard Worker         DISALLOW_COPY_AND_ASSIGN(LocalRef);
109*38e8c45fSAndroid Build Coastguard Worker 
110*38e8c45fSAndroid Build Coastguard Worker     private:
111*38e8c45fSAndroid Build Coastguard Worker         AutoBackendTexture* mTexture = nullptr;
112*38e8c45fSAndroid Build Coastguard Worker     };
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker private:
115*38e8c45fSAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(AutoBackendTexture);
116*38e8c45fSAndroid Build Coastguard Worker 
117*38e8c45fSAndroid Build Coastguard Worker     // Creates an AutoBackendTexture to manage the lifecycle of a given SkiaBackendTexture, which is
118*38e8c45fSAndroid Build Coastguard Worker     // in turn backed by an underlying backend-specific texture type.
119*38e8c45fSAndroid Build Coastguard Worker     AutoBackendTexture(std::unique_ptr<SkiaBackendTexture> backendTexture,
120*38e8c45fSAndroid Build Coastguard Worker                        CleanupManager& cleanupMgr);
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker     // The only way to invoke dtor is with unref, when mUsageCount is 0.
123*38e8c45fSAndroid Build Coastguard Worker     ~AutoBackendTexture() = default;
124*38e8c45fSAndroid Build Coastguard Worker 
ref()125*38e8c45fSAndroid Build Coastguard Worker     void ref() { mUsageCount++; }
126*38e8c45fSAndroid Build Coastguard Worker 
127*38e8c45fSAndroid Build Coastguard Worker     // releaseLocalResources is true if the underlying SkImage and SkSurface
128*38e8c45fSAndroid Build Coastguard Worker     // should be deleted from local tracking.
129*38e8c45fSAndroid Build Coastguard Worker     void unref(bool releaseLocalResources);
130*38e8c45fSAndroid Build Coastguard Worker 
131*38e8c45fSAndroid Build Coastguard Worker     // Makes a new SkImage from the texture content.
132*38e8c45fSAndroid Build Coastguard Worker     // As SkImages are immutable but buffer content is not, we create
133*38e8c45fSAndroid Build Coastguard Worker     // a new SkImage every time.
134*38e8c45fSAndroid Build Coastguard Worker     sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType);
135*38e8c45fSAndroid Build Coastguard Worker 
136*38e8c45fSAndroid Build Coastguard Worker     // Makes a new SkSurface from the texture content, if needed.
137*38e8c45fSAndroid Build Coastguard Worker     sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace);
138*38e8c45fSAndroid Build Coastguard Worker 
139*38e8c45fSAndroid Build Coastguard Worker     CleanupManager& mCleanupMgr;
140*38e8c45fSAndroid Build Coastguard Worker 
141*38e8c45fSAndroid Build Coastguard Worker     static void releaseSurfaceProc(SkSurface::ReleaseContext releaseContext);
142*38e8c45fSAndroid Build Coastguard Worker     static void releaseImageProc(SkImages::ReleaseContext releaseContext);
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<SkiaBackendTexture> mBackendTexture;
145*38e8c45fSAndroid Build Coastguard Worker     int mUsageCount = 0;
146*38e8c45fSAndroid Build Coastguard Worker     sk_sp<SkImage> mImage = nullptr;
147*38e8c45fSAndroid Build Coastguard Worker     sk_sp<SkSurface> mSurface = nullptr;
148*38e8c45fSAndroid Build Coastguard Worker     ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
149*38e8c45fSAndroid Build Coastguard Worker };
150*38e8c45fSAndroid Build Coastguard Worker 
151*38e8c45fSAndroid Build Coastguard Worker } // namespace skia
152*38e8c45fSAndroid Build Coastguard Worker } // namespace renderengine
153*38e8c45fSAndroid Build Coastguard Worker } // namespace android
154