Texture.h revision 66c3a829dc129b6081979facf5a652d5d9f1f51a
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
36namespace android {
37
38class GraphicBuffer;
39
40namespace uirenderer {
41
42class Caches;
43class UvMapper;
44class Layer;
45
46/**
47 * Represents an OpenGL texture.
48 */
49class Texture : public GpuMemoryTracker {
50public:
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
57    explicit Texture(Caches& caches)
58        : GpuMemoryTracker(GpuObjectType::Texture)
59        , mCaches(caches)
60    { }
61
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     */
90    void resize(uint32_t width, uint32_t height, GLint internalFormat, GLint format) {
91        upload(internalFormat, width, height, format, GL_UNSIGNED_BYTE, nullptr);
92    }
93
94    /**
95     * Updates this Texture with the contents of the provided Bitmap,
96     * also setting the appropriate width, height, and format. It is not necessary
97     * to call resize() prior to this.
98     *
99     * Note this does not set the generation from the Bitmap.
100     */
101    void upload(Bitmap& source);
102
103    /**
104     * Basically glTexImage2D/glTexSubImage2D.
105     */
106    void upload(GLint internalFormat, uint32_t width, uint32_t height,
107            GLenum format, GLenum type, const void* pixels);
108
109    /**
110     * Wraps an existing texture.
111     */
112    void wrap(GLuint id, uint32_t width, uint32_t height, GLint internalFormat,
113            GLint format, GLenum target);
114
115    GLuint id() const {
116        return mId;
117    }
118
119    uint32_t width() const {
120        return mWidth;
121    }
122
123    uint32_t height() const {
124        return mHeight;
125    }
126
127    GLint format() const {
128        return mFormat;
129    }
130
131    GLint internalFormat() const {
132        return mInternalFormat;
133    }
134
135    GLenum target() const {
136        return mTarget;
137    }
138
139    /**
140     * Returns nullptr if this texture does not require color space conversion
141     * to sRGB, or a valid pointer to a ColorSpaceConnector if a conversion
142     * is required.
143     */
144    constexpr const ColorSpaceConnector* getColorSpaceConnector() const {
145        return mConnector.get();
146    }
147
148    constexpr bool hasColorSpaceConversion() const {
149        return mConnector.get() != nullptr;
150    }
151
152    TransferFunctionType getTransferFunctionType() const;
153
154    /**
155     * Returns true if this texture uses a linear encoding format.
156     */
157    constexpr bool isLinear() const {
158        return mInternalFormat == GL_RGBA16F;
159    }
160
161    /**
162     * Generation of the backing bitmap,
163     */
164    uint32_t generation = 0;
165    /**
166     * Indicates whether the texture requires blending.
167     */
168    bool blend = false;
169    /**
170     * Indicates whether this texture should be cleaned up after use.
171     */
172    bool cleanup = false;
173    /**
174     * Optional, size of the original bitmap.
175     */
176    uint32_t bitmapSize = 0;
177    /**
178     * Indicates whether this texture will use trilinear filtering.
179     */
180    bool mipMap = false;
181
182    /**
183     * Optional, pointer to a texture coordinates mapper.
184     */
185    const UvMapper* uvMapper = nullptr;
186
187    /**
188     * Whether or not the Texture is marked in use and thus not evictable for
189     * the current frame. This is reset at the start of a new frame.
190     */
191    void* isInUse = nullptr;
192private:
193    // TODO: Temporarily grant private access to GlLayer, remove once
194    // GlLayer can be de-tangled from being a dual-purpose render target
195    // and external texture wrapper
196    friend class GlLayer;
197
198    // Returns true if the texture layout (size, format, etc.) changed, false if it was the same
199    bool updateLayout(uint32_t width, uint32_t height, GLint internalFormat,
200            GLint format, GLenum target);
201    void uploadHardwareBitmapToTexture(GraphicBuffer* buffer);
202    void resetCachedParams();
203
204    GLuint mId = 0;
205    uint32_t mWidth = 0;
206    uint32_t mHeight = 0;
207    GLint mFormat = 0;
208    GLint mInternalFormat = 0;
209    GLenum mTarget = GL_NONE;
210    EGLImageKHR mEglImageHandle = EGL_NO_IMAGE_KHR;
211
212    /* See GLES spec section 3.8.14
213     * "In the initial state, the value assigned to TEXTURE_MIN_FILTER is
214     * NEAREST_MIPMAP_LINEAR and the value for TEXTURE_MAG_FILTER is LINEAR.
215     * s, t, and r wrap modes are all set to REPEAT."
216     */
217    GLenum mWrapS = GL_REPEAT;
218    GLenum mWrapT = GL_REPEAT;
219    GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
220    GLenum mMagFilter = GL_LINEAR;
221
222    Caches& mCaches;
223
224    std::unique_ptr<ColorSpaceConnector> mConnector;
225}; // struct Texture
226
227class AutoTexture {
228public:
229    explicit AutoTexture(Texture* texture)
230            : texture(texture) {}
231    ~AutoTexture() {
232        if (texture && texture->cleanup) {
233            texture->deleteTexture();
234            delete texture;
235        }
236    }
237
238    Texture* const texture;
239}; // class AutoTexture
240
241}; // namespace uirenderer
242}; // namespace android
243
244#endif // ANDROID_HWUI_TEXTURE_H
245