blob: 1d5b5655db29c56c45fdbe9cf044acfa039a11b8 [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"
Nolan Scobiefc125ec2024-03-11 20:08:27 -040027#include "compat/SkiaGpuContext.h"
Alec Mouric7f6c8b2020-11-09 18:35:20 -080028
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040029#include <mutex>
30#include <vector>
31
Alec Mouric7f6c8b2020-11-09 18:35:20 -080032namespace android {
33namespace renderengine {
34namespace skia {
35
36/**
Ana Krulecdfec8f52021-01-13 12:51:47 -080037 * AutoBackendTexture manages GPU image lifetime. It is a ref-counted object
Alec Mouric7f6c8b2020-11-09 18:35:20 -080038 * that keeps GPU resources alive until the last SkImage or SkSurface object using them is
39 * destroyed.
40 */
41class AutoBackendTexture {
42public:
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040043 // Manager class that is responsible for the immediate or deferred cleanup
44 // of AutoBackendTextures. Clients of AutoBackendTexture are responsible for
45 // ensuring that access to this class is thread safe. Clients also control when
46 // the resources are reclaimed by setting the manager into deferred mode.
47 class CleanupManager {
48 public:
49 CleanupManager() = default;
50 void add(AutoBackendTexture* abt) {
51 if (mDeferCleanup) {
52 mCleanupList.push_back(abt);
53 } else {
54 delete abt;
55 }
56 }
57
58 void setDeferredStatus(bool enabled) { mDeferCleanup = enabled; }
59
60 bool isEmpty() const { return mCleanupList.empty(); }
61
62 // If any AutoBackedTextures were added while in deferred mode this method
63 // will ensure they are deleted before returning. It must only be called
64 // on the thread where the GPU context that created the AutoBackedTexture
65 // is active.
66 void cleanup() {
67 for (auto abt : mCleanupList) {
68 delete abt;
69 }
70 mCleanupList.clear();
71 }
72
73 private:
74 DISALLOW_COPY_AND_ASSIGN(CleanupManager);
75 bool mDeferCleanup = false;
76 std::vector<AutoBackendTexture*> mCleanupList;
77 };
78
Alec Mouric7f6c8b2020-11-09 18:35:20 -080079 // Local reference that supports RAII-style management of an AutoBackendTexture
80 // AutoBackendTexture by itself can't be managed in a similar fashion because
81 // of shared ownership with Skia objects, so we wrap it here instead.
82 class LocalRef {
83 public:
Nolan Scobiefc125ec2024-03-11 20:08:27 -040084 LocalRef(SkiaGpuContext* context, AHardwareBuffer* buffer, bool isOutputBuffer,
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040085 CleanupManager& cleanupMgr) {
86 mTexture = new AutoBackendTexture(context, buffer, isOutputBuffer, cleanupMgr);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -040087 mTexture->ref();
Alec Mouric7f6c8b2020-11-09 18:35:20 -080088 }
89
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -040090 ~LocalRef() {
91 if (mTexture != nullptr) {
92 mTexture->unref(true);
93 }
94 }
95
96 // Makes a new SkImage from the texture content.
97 // As SkImages are immutable but buffer content is not, we create
98 // a new SkImage every time.
Nolan Scobie17e25512024-03-13 18:02:48 -040099 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType) {
100 return mTexture->makeImage(dataspace, alphaType);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400101 }
102
103 // Makes a new SkSurface from the texture content, if needed.
Nolan Scobie17e25512024-03-13 18:02:48 -0400104 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace) {
105 return mTexture->getOrCreateSurface(dataspace);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400106 }
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:
Nolan Scobiefc125ec2024-03-11 20:08:27 -0400117 DISALLOW_COPY_AND_ASSIGN(AutoBackendTexture);
118
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800119 // Creates a GrBackendTexture whose contents come from the provided buffer.
Nolan Scobiefc125ec2024-03-11 20:08:27 -0400120 AutoBackendTexture(SkiaGpuContext* context, AHardwareBuffer* buffer, bool isOutputBuffer,
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400121 CleanupManager& cleanupMgr);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400122
123 // The only way to invoke dtor is with unref, when mUsageCount is 0.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400124 ~AutoBackendTexture();
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800125
126 void ref() { mUsageCount++; }
127
128 // releaseLocalResources is true if the underlying SkImage and SkSurface
129 // should be deleted from local tracking.
130 void unref(bool releaseLocalResources);
131
132 // Makes a new SkImage from the texture content.
133 // As SkImages are immutable but buffer content is not, we create
134 // a new SkImage every time.
Nolan Scobie17e25512024-03-13 18:02:48 -0400135 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800136
137 // Makes a new SkSurface from the texture content, if needed.
Nolan Scobie17e25512024-03-13 18:02:48 -0400138 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800139
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800140 GrBackendTexture mBackendTexture;
141 GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
142 GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
143 GrAHardwareBufferUtils::TexImageCtx mImageCtx;
144
Nolan Scobiefc125ec2024-03-11 20:08:27 -0400145 // TODO: b/293371537 - Graphite abstractions for ABT.
146 const sk_sp<GrDirectContext> mGrContext = nullptr;
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400147 CleanupManager& mCleanupMgr;
148
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800149 static void releaseSurfaceProc(SkSurface::ReleaseContext releaseContext);
Kevin Lubick95afb8a2023-05-11 14:57:41 +0000150 static void releaseImageProc(SkImages::ReleaseContext releaseContext);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800151
152 int mUsageCount = 0;
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400153 const bool mIsOutputBuffer;
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800154 sk_sp<SkImage> mImage = nullptr;
155 sk_sp<SkSurface> mSurface = nullptr;
156 ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
157 SkColorType mColorType = kUnknown_SkColorType;
158};
159
160} // namespace skia
161} // namespace renderengine
162} // namespace android