1ce0537b80087a6225273040a987414b1dd081aa0Romain Guy/*
2ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * Copyright (C) 2010 The Android Open Source Project
3ce0537b80087a6225273040a987414b1dd081aa0Romain Guy *
4ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * you may not use this file except in compliance with the License.
6ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * You may obtain a copy of the License at
7ce0537b80087a6225273040a987414b1dd081aa0Romain Guy *
8ce0537b80087a6225273040a987414b1dd081aa0Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9ce0537b80087a6225273040a987414b1dd081aa0Romain Guy *
10ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * Unless required by applicable law or agreed to in writing, software
11ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * See the License for the specific language governing permissions and
14ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * limitations under the License.
15ce0537b80087a6225273040a987414b1dd081aa0Romain Guy */
16ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ANDROID_HWUI_TEXTURE_H
185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ANDROID_HWUI_TEXTURE_H
19ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
2038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#include "GpuMemoryTracker.h"
2138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
22ce0537b80087a6225273040a987414b1dd081aa0Romain Guy#include <GLES2/gl2.h>
2338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#include <SkBitmap.h>
24ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
25ce0537b80087a6225273040a987414b1dd081aa0Romain Guynamespace android {
26ce0537b80087a6225273040a987414b1dd081aa0Romain Guynamespace uirenderer {
27ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
288aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guyclass Caches;
293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyclass UvMapper;
3038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckclass Layer;
313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
32ce0537b80087a6225273040a987414b1dd081aa0Romain Guy/**
33ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * Represents an OpenGL texture.
34ce0537b80087a6225273040a987414b1dd081aa0Romain Guy */
3538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reckclass Texture : public GpuMemoryTracker {
368aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guypublic:
3738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    Texture(Caches& caches)
3838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        : GpuMemoryTracker(GpuObjectType::Texture)
3938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        , mCaches(caches)
4038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    { }
419ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy
42a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy    virtual ~Texture() { }
43a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy
448aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    inline void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
45d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy                GLenum renderTarget = GL_TEXTURE_2D) {
46d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy        setWrapST(wrap, wrap, bindTexture, force, renderTarget);
47d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy    }
48d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy
49a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy    virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
508aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy            bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
51e3c26851dc315b730ea0fe5ef35bb1db81f6d675Romain Guy
528aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    inline void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
53d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy                GLenum renderTarget = GL_TEXTURE_2D) {
54d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy        setFilterMinMag(filter, filter, bindTexture, force, renderTarget);
55d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy    }
56d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy
57a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy    virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
588aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy            bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
5922158e139a3d6c6a9787ca0de224e9368f643284Romain Guy
60ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    /**
61be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy     * Convenience method to call glDeleteTextures() on this texture's id.
62be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy     */
6338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void deleteTexture();
64be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy
65be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy    /**
6638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * Sets the width, height, and format of the texture along with allocating
6738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * the texture ID. Does nothing if the width, height, and format are already
6838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * the requested values.
6938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     *
7038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * The image data is undefined after calling this.
71ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     */
7238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void resize(uint32_t width, uint32_t height, GLint format) {
7338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        upload(format, width, height, format, GL_UNSIGNED_BYTE, nullptr);
7438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
7538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
76ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    /**
7738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * Updates this Texture with the contents of the provided SkBitmap,
7838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * also setting the appropriate width, height, and format. It is not necessary
7938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * to call resize() prior to this.
8038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     *
8138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * Note this does not set the generation from the SkBitmap.
82fe8809471a40cac8acc984adfa51c39e13e83947Romain Guy     */
8338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void upload(const SkBitmap& source);
8438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
85fe8809471a40cac8acc984adfa51c39e13e83947Romain Guy    /**
8638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * Basically glTexImage2D/glTexSubImage2D.
87ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     */
8838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void upload(GLint internalformat, uint32_t width, uint32_t height,
8938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck            GLenum format, GLenum type, const void* pixels);
9038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
91ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    /**
9238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * Wraps an existing texture.
93ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     */
9438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    void wrap(GLuint id, uint32_t width, uint32_t height, GLint format);
9538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
9638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GLuint id() const {
9738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        return mId;
9838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
9938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
10038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    uint32_t width() const {
10138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        return mWidth;
10238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
10338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
10438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    uint32_t height() const {
10538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        return mHeight;
10638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
10738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
10838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GLint format() const {
10938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck        return mFormat;
11038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    }
11138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
112ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    /**
11338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * Generation of the backing bitmap,
114ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     */
11538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    uint32_t generation = 0;
11638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    /**
11738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     * Indicates whether the texture requires blending.
11838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck     */
11938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    bool blend = false;
12022158e139a3d6c6a9787ca0de224e9368f643284Romain Guy    /**
12122158e139a3d6c6a9787ca0de224e9368f643284Romain Guy     * Indicates whether this texture should be cleaned up after use.
12222158e139a3d6c6a9787ca0de224e9368f643284Romain Guy     */
123e2bb380bc26749782c873e5488cfdf4e42b27346Chris Craik    bool cleanup = false;
1249aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy    /**
1259aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy     * Optional, size of the original bitmap.
1269aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy     */
1278e93a7c9377b4ae43ecfb408f4906a09f6c83c03Chris Craik    uint32_t bitmapSize = 0;
128713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy    /**
129713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * Indicates whether this texture will use trilinear filtering.
130713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     */
1318e93a7c9377b4ae43ecfb408f4906a09f6c83c03Chris Craik    bool mipMap = false;
1328164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy
1333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Optional, pointer to a texture coordinates mapper.
1353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1368e93a7c9377b4ae43ecfb408f4906a09f6c83c03Chris Craik    const UvMapper* uvMapper = nullptr;
1373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
138860d155f866cc15a725e7ce03763280987f24901John Reck    /**
139860d155f866cc15a725e7ce03763280987f24901John Reck     * Whether or not the Texture is marked in use and thus not evictable for
140860d155f866cc15a725e7ce03763280987f24901John Reck     * the current frame. This is reset at the start of a new frame.
141860d155f866cc15a725e7ce03763280987f24901John Reck     */
14200e79c9947b741194ff6c0d08ede9b3befbf9c9dJohn Reck    void* isInUse = nullptr;
143860d155f866cc15a725e7ce03763280987f24901John Reck
144713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guyprivate:
14538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    // TODO: Temporarily grant private access to Layer, remove once
14638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    // Layer can be de-tangled from being a dual-purpose render target
14738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    // and external texture wrapper
14838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    friend class Layer;
14938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
15038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    // Returns true if the size changed, false if it was the same
15138e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    bool updateSize(uint32_t width, uint32_t height, GLint format);
15248247a2956f34d5d709660869273e0f7356e42b6John Reck    void resetCachedParams();
15338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
15438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GLuint mId = 0;
15538e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    uint32_t mWidth = 0;
15638e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    uint32_t mHeight = 0;
15738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    GLint mFormat = 0;
15838e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck
15948247a2956f34d5d709660869273e0f7356e42b6John Reck    /* See GLES spec section 3.8.14
16048247a2956f34d5d709660869273e0f7356e42b6John Reck     * "In the initial state, the value assigned to TEXTURE_MIN_FILTER is
16148247a2956f34d5d709660869273e0f7356e42b6John Reck     * NEAREST_MIPMAP_LINEAR and the value for TEXTURE_MAG_FILTER is LINEAR.
16248247a2956f34d5d709660869273e0f7356e42b6John Reck     * s, t, and r wrap modes are all set to REPEAT."
1638164c2d338781c3a3c4a443941070dca5d88f2a7Romain Guy     */
16448247a2956f34d5d709660869273e0f7356e42b6John Reck    GLenum mWrapS = GL_REPEAT;
16548247a2956f34d5d709660869273e0f7356e42b6John Reck    GLenum mWrapT = GL_REPEAT;
16648247a2956f34d5d709660869273e0f7356e42b6John Reck    GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
16748247a2956f34d5d709660869273e0f7356e42b6John Reck    GLenum mMagFilter = GL_LINEAR;
168e3c26851dc315b730ea0fe5ef35bb1db81f6d675Romain Guy
1698aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy    Caches& mCaches;
170ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}; // struct Texture
171ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
17222158e139a3d6c6a9787ca0de224e9368f643284Romain Guyclass AutoTexture {
17322158e139a3d6c6a9787ca0de224e9368f643284Romain Guypublic:
17438e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    AutoTexture(Texture* texture)
175386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            : texture(texture) {}
17622158e139a3d6c6a9787ca0de224e9368f643284Romain Guy    ~AutoTexture() {
177386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        if (texture && texture->cleanup) {
178386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            texture->deleteTexture();
179386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik            delete texture;
18022158e139a3d6c6a9787ca0de224e9368f643284Romain Guy        }
18122158e139a3d6c6a9787ca0de224e9368f643284Romain Guy    }
18222158e139a3d6c6a9787ca0de224e9368f643284Romain Guy
18338e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck    Texture* const texture;
18422158e139a3d6c6a9787ca0de224e9368f643284Romain Guy}; // class AutoTexture
18522158e139a3d6c6a9787ca0de224e9368f643284Romain Guy
186ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}; // namespace uirenderer
187ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}; // namespace android
188ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
1895b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_TEXTURE_H
190