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