blob: 30f4b77573788537f0e8aef3570d74cae5354af2 [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>
24
25#include "android-base/macros.h"
26#include "ui/GraphicTypes.h"
27
28namespace android {
29namespace renderengine {
30namespace skia {
31
32/**
33 * AutoBackendTexture manages GPU image lifetime. It is a ref-counted object
34 * that keeps GPU resources alive until the last SkImage or SkSurface object using them is
35 * destroyed.
36 */
37class AutoBackendTexture {
38public:
39 // Local reference that supports RAII-style management of an AutoBackendTexture
40 // AutoBackendTexture by itself can't be managed in a similar fashion because
41 // of shared ownership with Skia objects, so we wrap it here instead.
42 class LocalRef {
43 public:
44 LocalRef() {}
45
46 ~LocalRef() {
47 // Destroying the texture is the same as setting it to null
48 setTexture(nullptr);
49 }
50
51 // Sets the texture to locally ref-track.
52 void setTexture(AutoBackendTexture* texture) {
53 if (mTexture != nullptr) {
54 mTexture->unref(true);
55 }
56
57 mTexture = texture;
58 if (mTexture != nullptr) {
59 mTexture->ref();
60 }
61 }
62
63 AutoBackendTexture* getTexture() const { return mTexture; }
64
65 DISALLOW_COPY_AND_ASSIGN(LocalRef);
66
67 private:
68 AutoBackendTexture* mTexture = nullptr;
69 };
70
71 // Creates a GrBackendTexture whose contents come from the provided buffer.
72 AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer, bool isRender);
73
74 void ref() { mUsageCount++; }
75
76 // releaseLocalResources is true if the underlying SkImage and SkSurface
77 // should be deleted from local tracking.
78 void unref(bool releaseLocalResources);
79
80 // Makes a new SkImage from the texture content.
81 // As SkImages are immutable but buffer content is not, we create
82 // a new SkImage every time.
83 sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType,
84 GrDirectContext* context);
85
86 // Makes a new SkSurface from the texture content, if needed.
87 sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace, GrDirectContext* context);
88
89private:
90 // The only way to invoke dtor is with unref, when mUsageCount is 0.
91 ~AutoBackendTexture() {}
92
93 GrBackendTexture mBackendTexture;
94 GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
95 GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
96 GrAHardwareBufferUtils::TexImageCtx mImageCtx;
97
98 static void releaseSurfaceProc(SkSurface::ReleaseContext releaseContext);
99 static void releaseImageProc(SkImage::ReleaseContext releaseContext);
100
101 int mUsageCount = 0;
102
103 sk_sp<SkImage> mImage = nullptr;
104 sk_sp<SkSurface> mSurface = nullptr;
105 ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
106 SkColorType mColorType = kUnknown_SkColorType;
107};
108
109} // namespace skia
110} // namespace renderengine
111} // namespace android