blob: 509ac40f77f89344dba565b5af29e47819ec66fe [file] [log] [blame]
Alec Mouric7f6c8b2020-11-09 18:35:20 -08001/*
2 * Copyright 2020 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#pragma once
18
19#include <GrAHardwareBufferUtils.h>
20#include <GrDirectContext.h>
21#include <SkImage.h>
22#include <SkSurface.h>
23#include <sys/types.h>
Alec Mouria90a5702021-04-16 16:36:21 +000024#include <ui/GraphicTypes.h>
Alec Mouric7f6c8b2020-11-09 18:35:20 -080025
26#include "android-base/macros.h"
Alec Mouric7f6c8b2020-11-09 18:35:20 -080027
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040028#include <mutex>
29#include <vector>
30
Alec Mouric7f6c8b2020-11-09 18:35:20 -080031namespace android {
32namespace renderengine {
33namespace skia {
34
35/**
Ana Krulecdfec8f52021-01-13 12:51:47 -080036 * AutoBackendTexture manages GPU image lifetime. It is a ref-counted object
Alec Mouric7f6c8b2020-11-09 18:35:20 -080037 * that keeps GPU resources alive until the last SkImage or SkSurface object using them is
38 * destroyed.
39 */
40class AutoBackendTexture {
41public:
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040042 // Manager class that is responsible for the immediate or deferred cleanup
43 // of AutoBackendTextures. Clients of AutoBackendTexture are responsible for
44 // ensuring that access to this class is thread safe. Clients also control when
45 // the resources are reclaimed by setting the manager into deferred mode.
46 class CleanupManager {
47 public:
48 CleanupManager() = default;
49 void add(AutoBackendTexture* abt) {
50 if (mDeferCleanup) {
51 mCleanupList.push_back(abt);
52 } else {
53 delete abt;
54 }
55 }
56
57 void setDeferredStatus(bool enabled) { mDeferCleanup = enabled; }
58
59 bool isEmpty() const { return mCleanupList.empty(); }
60
61 // If any AutoBackedTextures were added while in deferred mode this method
62 // will ensure they are deleted before returning. It must only be called
63 // on the thread where the GPU context that created the AutoBackedTexture
64 // is active.
65 void cleanup() {
66 for (auto abt : mCleanupList) {
67 delete abt;
68 }
69 mCleanupList.clear();
70 }
71
72 private:
73 DISALLOW_COPY_AND_ASSIGN(CleanupManager);
74 bool mDeferCleanup = false;
75 std::vector<AutoBackendTexture*> mCleanupList;
76 };
77
Alec Mouric7f6c8b2020-11-09 18:35:20 -080078 // Local reference that supports RAII-style management of an AutoBackendTexture
79 // AutoBackendTexture by itself can't be managed in a similar fashion because
80 // of shared ownership with Skia objects, so we wrap it here instead.
81 class LocalRef {
82 public:
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040083 LocalRef(GrDirectContext* context, AHardwareBuffer* buffer, bool isOutputBuffer,
84 CleanupManager& cleanupMgr) {
85 mTexture = new AutoBackendTexture(context, buffer, isOutputBuffer, cleanupMgr);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -040086 mTexture->ref();
Alec Mouric7f6c8b2020-11-09 18:35:20 -080087 }
88
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -040089 ~LocalRef() {
90 if (mTexture != nullptr) {
91 mTexture->unref(true);
92 }
93 }
94
95 // Makes a new SkImage from the texture content.
96 // As SkImages are immutable but buffer content is not, we create
97 // a new SkImage every time.
98 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType,
99 GrDirectContext* context) {
100 return mTexture->makeImage(dataspace, alphaType, context);
101 }
102
103 // Makes a new SkSurface from the texture content, if needed.
104 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace, GrDirectContext* context) {
105 return mTexture->getOrCreateSurface(dataspace, context);
106 }
Alec Mouria90a5702021-04-16 16:36:21 +0000107
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400108 SkColorType colorType() const { return mTexture->mColorType; }
109
Alec Mouria90a5702021-04-16 16:36:21 +0000110 DISALLOW_COPY_AND_ASSIGN(LocalRef);
111
112 private:
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800113 AutoBackendTexture* mTexture = nullptr;
114 };
115
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400116private:
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800117 // Creates a GrBackendTexture whose contents come from the provided buffer.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400118 AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer, bool isOutputBuffer,
119 CleanupManager& cleanupMgr);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400120
121 // The only way to invoke dtor is with unref, when mUsageCount is 0.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400122 ~AutoBackendTexture();
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800123
124 void ref() { mUsageCount++; }
125
126 // releaseLocalResources is true if the underlying SkImage and SkSurface
127 // should be deleted from local tracking.
128 void unref(bool releaseLocalResources);
129
130 // Makes a new SkImage from the texture content.
131 // As SkImages are immutable but buffer content is not, we create
132 // a new SkImage every time.
133 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType,
134 GrDirectContext* context);
135
136 // Makes a new SkSurface from the texture content, if needed.
137 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace, GrDirectContext* context);
138
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800139 GrBackendTexture mBackendTexture;
140 GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
141 GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
142 GrAHardwareBufferUtils::TexImageCtx mImageCtx;
143
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400144 CleanupManager& mCleanupMgr;
145
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800146 static void releaseSurfaceProc(SkSurface::ReleaseContext releaseContext);
Kevin Lubick95afb8a2023-05-11 14:57:41 +0000147 static void releaseImageProc(SkImages::ReleaseContext releaseContext);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800148
149 int mUsageCount = 0;
150
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400151 const bool mIsOutputBuffer;
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800152 sk_sp<SkImage> mImage = nullptr;
153 sk_sp<SkSurface> mSurface = nullptr;
154 ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
155 SkColorType mColorType = kUnknown_SkColorType;
156};
157
158} // namespace skia
159} // namespace renderengine
160} // namespace android