blob: 17e183a64e36f3e3d5b01c56a175d5825d35196c [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.
Nolan Scobie17e25512024-03-13 18:02:48 -040098 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType) {
99 return mTexture->makeImage(dataspace, alphaType);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400100 }
101
102 // Makes a new SkSurface from the texture content, if needed.
Nolan Scobie17e25512024-03-13 18:02:48 -0400103 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace) {
104 return mTexture->getOrCreateSurface(dataspace);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400105 }
Alec Mouria90a5702021-04-16 16:36:21 +0000106
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400107 SkColorType colorType() const { return mTexture->mColorType; }
108
Alec Mouria90a5702021-04-16 16:36:21 +0000109 DISALLOW_COPY_AND_ASSIGN(LocalRef);
110
111 private:
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800112 AutoBackendTexture* mTexture = nullptr;
113 };
114
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400115private:
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800116 // Creates a GrBackendTexture whose contents come from the provided buffer.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400117 AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer, bool isOutputBuffer,
118 CleanupManager& cleanupMgr);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400119
120 // The only way to invoke dtor is with unref, when mUsageCount is 0.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400121 ~AutoBackendTexture();
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800122
123 void ref() { mUsageCount++; }
124
125 // releaseLocalResources is true if the underlying SkImage and SkSurface
126 // should be deleted from local tracking.
127 void unref(bool releaseLocalResources);
128
129 // Makes a new SkImage from the texture content.
130 // As SkImages are immutable but buffer content is not, we create
131 // a new SkImage every time.
Nolan Scobie17e25512024-03-13 18:02:48 -0400132 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800133
134 // Makes a new SkSurface from the texture content, if needed.
Nolan Scobie17e25512024-03-13 18:02:48 -0400135 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800136
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800137 GrBackendTexture mBackendTexture;
138 GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
139 GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
140 GrAHardwareBufferUtils::TexImageCtx mImageCtx;
141
Nolan Scobie17e25512024-03-13 18:02:48 -0400142 const GrDirectContext* mGrContext = nullptr;
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400143 CleanupManager& mCleanupMgr;
144
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800145 static void releaseSurfaceProc(SkSurface::ReleaseContext releaseContext);
Kevin Lubick95afb8a2023-05-11 14:57:41 +0000146 static void releaseImageProc(SkImages::ReleaseContext releaseContext);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800147
148 int mUsageCount = 0;
149
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400150 const bool mIsOutputBuffer;
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800151 sk_sp<SkImage> mImage = nullptr;
152 sk_sp<SkSurface> mSurface = nullptr;
153 ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
154 SkColorType mColorType = kUnknown_SkColorType;
155};
156
157} // namespace skia
158} // namespace renderengine
159} // namespace android