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 Texture(Caches & caches)58 explicit Texture(Caches& caches) : GpuMemoryTracker(GpuObjectType::Texture), mCaches(caches) {} 59 ~Texture()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 */ resize(uint32_t width,uint32_t height,GLint internalFormat,GLint format)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 id()114 GLuint id() const { return mId; } 115 width()116 uint32_t width() const { return mWidth; } 117 height()118 uint32_t height() const { return mHeight; } 119 format()120 GLint format() const { return mFormat; } 121 internalFormat()122 GLint internalFormat() const { return mInternalFormat; } 123 target()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 */ getColorSpaceConnector()131 constexpr const ColorSpaceConnector* getColorSpaceConnector() const { return mConnector.get(); } 132 hasColorSpaceConversion()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 */ isLinear()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: AutoTexture(Texture * texture)214 explicit AutoTexture(Texture* texture) : texture(texture) {} ~AutoTexture()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