blob: a570ad01a294d0ee150a9ddcfda7cece652db039 [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
Alec Mouric7f6c8b2020-11-09 18:35:20 -080019#include <SkImage.h>
20#include <SkSurface.h>
Nolan Scobiebc3f3602024-08-30 13:51:37 -040021#include <include/gpu/ganesh/GrDirectContext.h>
Alec Mouric7f6c8b2020-11-09 18:35:20 -080022#include <sys/types.h>
Alec Mouria90a5702021-04-16 16:36:21 +000023#include <ui/GraphicTypes.h>
Alec Mouric7f6c8b2020-11-09 18:35:20 -080024
25#include "android-base/macros.h"
Nolan Scobieca050282024-03-15 13:27:06 -040026#include "compat/SkiaBackendTexture.h"
Alec Mouric7f6c8b2020-11-09 18:35:20 -080027
Nolan Scobieca050282024-03-15 13:27:06 -040028#include <memory>
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040029#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:
Nolan Scobieca050282024-03-15 13:27:06 -040083 LocalRef(std::unique_ptr<SkiaBackendTexture> backendTexture, CleanupManager& cleanupMgr) {
84 mTexture = new AutoBackendTexture(std::move(backendTexture), cleanupMgr);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -040085 mTexture->ref();
Alec Mouric7f6c8b2020-11-09 18:35:20 -080086 }
87
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -040088 ~LocalRef() {
89 if (mTexture != nullptr) {
90 mTexture->unref(true);
91 }
92 }
93
94 // Makes a new SkImage from the texture content.
95 // As SkImages are immutable but buffer content is not, we create
96 // a new SkImage every time.
Nolan Scobie17e25512024-03-13 18:02:48 -040097 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType) {
98 return mTexture->makeImage(dataspace, alphaType);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -040099 }
100
101 // Makes a new SkSurface from the texture content, if needed.
Nolan Scobie17e25512024-03-13 18:02:48 -0400102 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace) {
103 return mTexture->getOrCreateSurface(dataspace);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400104 }
Alec Mouria90a5702021-04-16 16:36:21 +0000105
Nolan Scobieca050282024-03-15 13:27:06 -0400106 SkColorType colorType() const { return mTexture->mBackendTexture->internalColorType(); }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400107
Alec Mouria90a5702021-04-16 16:36:21 +0000108 DISALLOW_COPY_AND_ASSIGN(LocalRef);
109
110 private:
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800111 AutoBackendTexture* mTexture = nullptr;
112 };
113
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400114private:
Nolan Scobiefc125ec2024-03-11 20:08:27 -0400115 DISALLOW_COPY_AND_ASSIGN(AutoBackendTexture);
116
Nolan Scobieca050282024-03-15 13:27:06 -0400117 // Creates an AutoBackendTexture to manage the lifecycle of a given SkiaBackendTexture, which is
118 // in turn backed by an underlying backend-specific texture type.
119 AutoBackendTexture(std::unique_ptr<SkiaBackendTexture> backendTexture,
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400120 CleanupManager& cleanupMgr);
Derek Sollenbergerd8fdae32021-04-09 13:52:59 -0400121
122 // The only way to invoke dtor is with unref, when mUsageCount is 0.
Nolan Scobieca050282024-03-15 13:27:06 -0400123 ~AutoBackendTexture() = default;
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800124
125 void ref() { mUsageCount++; }
126
127 // releaseLocalResources is true if the underlying SkImage and SkSurface
128 // should be deleted from local tracking.
129 void unref(bool releaseLocalResources);
130
131 // Makes a new SkImage from the texture content.
132 // As SkImages are immutable but buffer content is not, we create
133 // a new SkImage every time.
Nolan Scobie17e25512024-03-13 18:02:48 -0400134 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800135
136 // Makes a new SkSurface from the texture content, if needed.
Nolan Scobie17e25512024-03-13 18:02:48 -0400137 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800138
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400139 CleanupManager& mCleanupMgr;
140
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800141 static void releaseSurfaceProc(SkSurface::ReleaseContext releaseContext);
Kevin Lubick95afb8a2023-05-11 14:57:41 +0000142 static void releaseImageProc(SkImages::ReleaseContext releaseContext);
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800143
Nolan Scobieca050282024-03-15 13:27:06 -0400144 std::unique_ptr<SkiaBackendTexture> mBackendTexture;
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800145 int mUsageCount = 0;
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800146 sk_sp<SkImage> mImage = nullptr;
147 sk_sp<SkSurface> mSurface = nullptr;
148 ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
Alec Mouric7f6c8b2020-11-09 18:35:20 -0800149};
150
151} // namespace skia
152} // namespace renderengine
153} // namespace android