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