• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 #ifndef ANDROID_HWUI_TEXTURE_H
18 #define ANDROID_HWUI_TEXTURE_H
19 
20 #include "GpuMemoryTracker.h"
21 #include "hwui/Bitmap.h"
22 #include "utils/Color.h"
23 
24 #include <memory>
25 
26 #include <math/mat3.h>
27 
28 #include <ui/ColorSpace.h>
29 
30 #include <GLES2/gl2.h>
31 #include <GLES3/gl3.h>
32 #include <EGL/egl.h>
33 #include <EGL/eglext.h>
34 #include <SkBitmap.h>
35 
36 namespace android {
37 
38 class GraphicBuffer;
39 
40 namespace uirenderer {
41 
42 class Caches;
43 class UvMapper;
44 class Layer;
45 
46 /**
47  * Represents an OpenGL texture.
48  */
49 class Texture : public GpuMemoryTracker {
50 public:
51     static SkBitmap uploadToN32(const SkBitmap& bitmap,
52             bool hasLinearBlending, sk_sp<SkColorSpace> sRGB);
53     static bool hasUnsupportedColorType(const SkImageInfo& info, bool hasLinearBlending);
54     static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
55             bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType);
56 
Texture(Caches & caches)57     explicit Texture(Caches& caches)
58         : GpuMemoryTracker(GpuObjectType::Texture)
59         , mCaches(caches)
60     { }
61 
~Texture()62     virtual ~Texture() { }
63 
64     inline void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
65         setWrapST(wrap, wrap, bindTexture, force);
66     }
67 
68     virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
69             bool force = false);
70 
71     inline void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
72         setFilterMinMag(filter, filter, bindTexture, force);
73     }
74 
75     virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
76             bool force = false);
77 
78     /**
79      * Convenience method to call glDeleteTextures() on this texture's id.
80      */
81     void deleteTexture();
82 
83     /**
84      * Sets the width, height, and format of the texture along with allocating
85      * the texture ID. Does nothing if the width, height, and format are already
86      * the requested values.
87      *
88      * The image data is undefined after calling this.
89      */
resize(uint32_t width,uint32_t height,GLint internalFormat,GLint format)90     void resize(uint32_t width, uint32_t height, GLint internalFormat, GLint format) {
91         upload(internalFormat, width, height, format,
92                 internalFormat == GL_RGBA16F ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE, nullptr);
93     }
94 
95     /**
96      * Updates this Texture with the contents of the provided Bitmap,
97      * also setting the appropriate width, height, and format. It is not necessary
98      * to call resize() prior to this.
99      *
100      * Note this does not set the generation from the Bitmap.
101      */
102     void upload(Bitmap& source);
103 
104     /**
105      * Basically glTexImage2D/glTexSubImage2D.
106      */
107     void upload(GLint internalFormat, uint32_t width, uint32_t height,
108             GLenum format, GLenum type, const void* pixels);
109 
110     /**
111      * Wraps an existing texture.
112      */
113     void wrap(GLuint id, uint32_t width, uint32_t height, GLint internalFormat,
114             GLint format, GLenum target);
115 
id()116     GLuint id() const {
117         return mId;
118     }
119 
width()120     uint32_t width() const {
121         return mWidth;
122     }
123 
height()124     uint32_t height() const {
125         return mHeight;
126     }
127 
format()128     GLint format() const {
129         return mFormat;
130     }
131 
internalFormat()132     GLint internalFormat() const {
133         return mInternalFormat;
134     }
135 
target()136     GLenum target() const {
137         return mTarget;
138     }
139 
140     /**
141      * Returns nullptr if this texture does not require color space conversion
142      * to sRGB, or a valid pointer to a ColorSpaceConnector if a conversion
143      * is required.
144      */
getColorSpaceConnector()145     constexpr const ColorSpaceConnector* getColorSpaceConnector() const {
146         return mConnector.get();
147     }
148 
hasColorSpaceConversion()149     constexpr bool hasColorSpaceConversion() const {
150         return mConnector.get() != nullptr;
151     }
152 
153     TransferFunctionType getTransferFunctionType() const;
154 
155     /**
156      * Returns true if this texture uses a linear encoding format.
157      */
isLinear()158     constexpr bool isLinear() const {
159         return mIsLinear;
160     }
161 
162     /**
163      * Generation of the backing bitmap,
164      */
165     uint32_t generation = 0;
166     /**
167      * Indicates whether the texture requires blending.
168      */
169     bool blend = false;
170     /**
171      * Indicates whether this texture should be cleaned up after use.
172      */
173     bool cleanup = false;
174     /**
175      * Optional, size of the original bitmap.
176      */
177     uint32_t bitmapSize = 0;
178     /**
179      * Indicates whether this texture will use trilinear filtering.
180      */
181     bool mipMap = false;
182 
183     /**
184      * Optional, pointer to a texture coordinates mapper.
185      */
186     const UvMapper* uvMapper = nullptr;
187 
188     /**
189      * Whether or not the Texture is marked in use and thus not evictable for
190      * the current frame. This is reset at the start of a new frame.
191      */
192     void* isInUse = nullptr;
193 private:
194     // TODO: Temporarily grant private access to GlLayer, remove once
195     // GlLayer can be de-tangled from being a dual-purpose render target
196     // and external texture wrapper
197     friend class GlLayer;
198 
199     // Returns true if the texture layout (size, format, etc.) changed, false if it was the same
200     bool updateLayout(uint32_t width, uint32_t height, GLint internalFormat,
201             GLint format, GLenum target);
202     void uploadHardwareBitmapToTexture(GraphicBuffer* buffer);
203     void resetCachedParams();
204 
205     GLuint mId = 0;
206     uint32_t mWidth = 0;
207     uint32_t mHeight = 0;
208     GLint mFormat = 0;
209     GLint mInternalFormat = 0;
210     GLenum mTarget = GL_NONE;
211     EGLImageKHR mEglImageHandle = EGL_NO_IMAGE_KHR;
212 
213     /* See GLES spec section 3.8.14
214      * "In the initial state, the value assigned to TEXTURE_MIN_FILTER is
215      * NEAREST_MIPMAP_LINEAR and the value for TEXTURE_MAG_FILTER is LINEAR.
216      * s, t, and r wrap modes are all set to REPEAT."
217      */
218     GLenum mWrapS = GL_REPEAT;
219     GLenum mWrapT = GL_REPEAT;
220     GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
221     GLenum mMagFilter = GL_LINEAR;
222 
223     // Indicates whether the content of the texture is in linear space
224     bool mIsLinear = false;
225 
226     Caches& mCaches;
227 
228     std::unique_ptr<ColorSpaceConnector> mConnector;
229 }; // struct Texture
230 
231 class AutoTexture {
232 public:
AutoTexture(Texture * texture)233     explicit AutoTexture(Texture* texture)
234             : texture(texture) {}
~AutoTexture()235     ~AutoTexture() {
236         if (texture && texture->cleanup) {
237             texture->deleteTexture();
238             delete texture;
239         }
240     }
241 
242     Texture* const texture;
243 }; // class AutoTexture
244 
245 }; // namespace uirenderer
246 }; // namespace android
247 
248 #endif // ANDROID_HWUI_TEXTURE_H
249