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