1 /* 2 Copyright 2011 Google Inc. 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 GrGLTexture_DEFINED 18 #define GrGLTexture_DEFINED 19 20 #include "GrTexture.h" 21 #include "GrScalar.h" 22 #include "GrGLIRect.h" 23 24 class GrGpuGL; 25 class GrGLTexture; 26 27 /** 28 * A ref counted tex id that deletes the texture in its destructor. 29 */ 30 class GrGLTexID : public GrRefCnt { 31 32 public: 33 GrGLTexID(GrGLuint texID, bool ownsID) : fTexID(texID), fOwnsID(ownsID) {} 34 35 virtual ~GrGLTexID() { 36 if (0 != fTexID && fOwnsID) { 37 GR_GL(DeleteTextures(1, &fTexID)); 38 } 39 } 40 41 void abandon() { fTexID = 0; } 42 GrGLuint id() const { return fTexID; } 43 44 private: 45 GrGLuint fTexID; 46 bool fOwnsID; 47 }; 48 49 //////////////////////////////////////////////////////////////////////////////// 50 51 class GrGLRenderTarget : public GrRenderTarget { 52 53 public: 54 // set fTexFBOID to this value to indicate that it is multisampled but 55 // Gr doesn't know how to resolve it. 56 enum { kUnresolvableFBOID = 0 }; 57 58 struct GLRenderTargetIDs { 59 GrGLuint fRTFBOID; 60 GrGLuint fTexFBOID; 61 GrGLuint fStencilRenderbufferID; 62 GrGLuint fMSColorRenderbufferID; 63 bool fOwnIDs; 64 void reset() { memset(this, 0, sizeof(GLRenderTargetIDs)); } 65 }; 66 67 GrGLRenderTarget(GrGpuGL* gpu, 68 const GLRenderTargetIDs& ids, 69 GrGLTexID* texID, 70 GrGLuint stencilBits, 71 bool isMultisampled, 72 const GrGLIRect& fViewport, 73 GrGLTexture* texture); 74 75 virtual ~GrGLRenderTarget() { this->release(); } 76 77 void setViewport(const GrGLIRect& rect) { fViewport = rect; } 78 const GrGLIRect& getViewport() const { return fViewport; } 79 80 // The following two functions return the same ID when a 81 // texture-rendertarget is multisampled, and different IDs when 82 // it is. 83 // FBO ID used to render into 84 GrGLuint renderFBOID() const { return fRTFBOID; } 85 // FBO ID that has texture ID attached. 86 GrGLuint textureFBOID() const { return fTexFBOID; } 87 88 // override of GrRenderTarget 89 virtual ResolveType getResolveType() const { 90 if (fRTFBOID == fTexFBOID) { 91 // catches FBO 0 and non MSAA case 92 return kAutoResolves_ResolveType; 93 } else if (kUnresolvableFBOID == fTexFBOID) { 94 return kCantResolve_ResolveType; 95 } else { 96 return kCanResolve_ResolveType; 97 } 98 } 99 100 protected: 101 // override of GrResource 102 virtual void onAbandon(); 103 virtual void onRelease(); 104 105 private: 106 GrGLuint fRTFBOID; 107 GrGLuint fTexFBOID; 108 GrGLuint fStencilRenderbufferID; 109 GrGLuint fMSColorRenderbufferID; 110 111 // Should this object delete IDs when it is destroyed or does someone 112 // else own them. 113 bool fOwnIDs; 114 115 // when we switch to this rendertarget we want to set the viewport to 116 // only render to to content area (as opposed to the whole allocation) and 117 // we want the rendering to be at top left (GL has origin in bottom left) 118 GrGLIRect fViewport; 119 120 // non-NULL if this RT was created by Gr with an associated GrGLTexture. 121 GrGLTexID* fTexIDObj; 122 123 typedef GrRenderTarget INHERITED; 124 }; 125 126 //////////////////////////////////////////////////////////////////////////////// 127 128 class GrGLTexture : public GrTexture { 129 130 public: 131 enum Orientation { 132 kBottomUp_Orientation, 133 kTopDown_Orientation, 134 }; 135 136 struct TexParams { 137 GrGLenum fFilter; 138 GrGLenum fWrapS; 139 GrGLenum fWrapT; 140 void invalidate() { memset(this, 0xff, sizeof(TexParams)); } 141 }; 142 143 struct GLTextureDesc { 144 uint32_t fContentWidth; 145 uint32_t fContentHeight; 146 uint32_t fAllocWidth; 147 uint32_t fAllocHeight; 148 GrPixelConfig fFormat; 149 GrGLuint fTextureID; 150 bool fOwnsID; 151 GrGLenum fUploadFormat; 152 GrGLenum fUploadByteCount; 153 GrGLenum fUploadType; 154 GrGLuint fStencilBits; 155 Orientation fOrientation; 156 }; 157 158 typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs; 159 160 GrGLTexture(GrGpuGL* gpu, 161 const GLTextureDesc& textureDesc, 162 const GLRenderTargetIDs& rtIDs, 163 const TexParams& initialTexParams); 164 165 virtual ~GrGLTexture() { this->release(); } 166 167 // overrides of GrTexture 168 virtual void uploadTextureData(uint32_t x, 169 uint32_t y, 170 uint32_t width, 171 uint32_t height, 172 const void* srcData); 173 virtual intptr_t getTextureHandle(); 174 175 const TexParams& getTexParams() const { return fTexParams; } 176 void setTexParams(const TexParams& texParams) { fTexParams = texParams; } 177 GrGLuint textureID() const { return fTexIDObj->id(); } 178 179 GrGLenum uploadFormat() const { return fUploadFormat; } 180 GrGLenum uploadByteCount() const { return fUploadByteCount; } 181 GrGLenum uploadType() const { return fUploadType; } 182 183 /** 184 * Retrieves the texture width actually allocated in texels. 185 * 186 * @return the width in texels 187 */ 188 int allocWidth() const { return fAllocWidth; } 189 190 /** 191 * Retrieves the texture height actually allocated in texels. 192 * 193 * @return the height in texels 194 */ 195 int allocHeight() const { return fAllocHeight; } 196 197 /** 198 * @return width() / allocWidth() 199 */ 200 GrScalar contentScaleX() const { return fScaleX; } 201 202 /** 203 * @return height() / allocHeight() 204 */ 205 GrScalar contentScaleY() const { return fScaleY; } 206 207 // Ganesh assumes texture coordinates have their origin 208 // in the top-left corner of the image. OpenGL, however, 209 // has the origin in the lower-left corner. For content that 210 // is loaded by Ganesh we just push the content "upside down" 211 // (by GL's understanding of the world ) in glTex*Image and the 212 // addressing just works out. However, content generated by GL 213 // (FBO or externally imported texture) will be updside down 214 // and it is up to the GrGpuGL derivative to handle y-mirroing. 215 Orientation orientation() const { return fOrientation; } 216 217 static const GrGLenum* WrapMode2GLWrap(); 218 219 protected: 220 221 // overrides of GrTexture 222 virtual void onAbandon(); 223 virtual void onRelease(); 224 225 private: 226 TexParams fTexParams; 227 GrGLTexID* fTexIDObj; 228 GrGLenum fUploadFormat; 229 GrGLenum fUploadByteCount; 230 GrGLenum fUploadType; 231 int fAllocWidth; 232 int fAllocHeight; 233 // precomputed content / alloc ratios 234 GrScalar fScaleX; 235 GrScalar fScaleY; 236 Orientation fOrientation; 237 GrGpuGL* fGpuGL; 238 239 typedef GrTexture INHERITED; 240 }; 241 242 #endif 243