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