1 // 2 // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Texture.h: Defines the gl::Texture class [OpenGL ES 2.0.24] section 3.7 page 63. 8 9 #ifndef LIBANGLE_TEXTURE_H_ 10 #define LIBANGLE_TEXTURE_H_ 11 12 #include <map> 13 #include <vector> 14 15 #include "angle_gl.h" 16 #include "common/Optional.h" 17 #include "common/debug.h" 18 #include "common/utilities.h" 19 #include "libANGLE/Caps.h" 20 #include "libANGLE/Constants.h" 21 #include "libANGLE/Debug.h" 22 #include "libANGLE/Error.h" 23 #include "libANGLE/FramebufferAttachment.h" 24 #include "libANGLE/Image.h" 25 #include "libANGLE/Observer.h" 26 #include "libANGLE/Stream.h" 27 #include "libANGLE/angletypes.h" 28 #include "libANGLE/formatutils.h" 29 30 namespace egl 31 { 32 class Surface; 33 class Stream; 34 } // namespace egl 35 36 namespace rx 37 { 38 class GLImplFactory; 39 class TextureImpl; 40 class TextureGL; 41 } // namespace rx 42 43 namespace gl 44 { 45 class Framebuffer; 46 class MemoryObject; 47 class Sampler; 48 class State; 49 class Texture; 50 51 bool IsMipmapFiltered(const SamplerState &samplerState); 52 53 struct ImageDesc final 54 { 55 ImageDesc(); 56 ImageDesc(const Extents &size, const Format &format, const InitState initState); 57 ImageDesc(const Extents &size, 58 const Format &format, 59 const GLsizei samples, 60 const bool fixedSampleLocations, 61 const InitState initState); 62 63 ImageDesc(const ImageDesc &other) = default; 64 ImageDesc &operator=(const ImageDesc &other) = default; 65 66 GLint getMemorySize() const; 67 68 Extents size; 69 Format format; 70 GLsizei samples; 71 bool fixedSampleLocations; 72 73 // Needed for robust resource initialization. 74 InitState initState; 75 }; 76 77 struct SwizzleState final 78 { 79 SwizzleState(); 80 SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha); 81 SwizzleState(const SwizzleState &other) = default; 82 SwizzleState &operator=(const SwizzleState &other) = default; 83 84 bool swizzleRequired() const; 85 86 bool operator==(const SwizzleState &other) const; 87 bool operator!=(const SwizzleState &other) const; 88 89 GLenum swizzleRed; 90 GLenum swizzleGreen; 91 GLenum swizzleBlue; 92 GLenum swizzleAlpha; 93 }; 94 95 // State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec. 96 class TextureState final : private angle::NonCopyable 97 { 98 public: 99 TextureState(TextureType type); 100 ~TextureState(); 101 102 bool swizzleRequired() const; 103 GLuint getEffectiveBaseLevel() const; 104 GLuint getEffectiveMaxLevel() const; 105 106 // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. 107 GLuint getMipmapMaxLevel() const; 108 109 // Returns true if base level changed. 110 bool setBaseLevel(GLuint baseLevel); 111 bool setMaxLevel(GLuint maxLevel); 112 113 bool isCubeComplete() const; 114 compatibleWithSamplerFormat(SamplerFormat format,const SamplerState & samplerState)115 ANGLE_INLINE bool compatibleWithSamplerFormat(SamplerFormat format, 116 const SamplerState &samplerState) const 117 { 118 if (!mCachedSamplerFormatValid || 119 mCachedSamplerCompareMode != samplerState.getCompareMode()) 120 { 121 mCachedSamplerFormat = computeRequiredSamplerFormat(samplerState); 122 mCachedSamplerCompareMode = samplerState.getCompareMode(); 123 mCachedSamplerFormatValid = true; 124 } 125 // Incomplete textures are compatible with any sampler format. 126 return mCachedSamplerFormat == SamplerFormat::InvalidEnum || format == mCachedSamplerFormat; 127 } 128 129 const ImageDesc &getImageDesc(TextureTarget target, size_t level) const; 130 const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const; 131 getType()132 TextureType getType() const { return mType; } getSwizzleState()133 const SwizzleState &getSwizzleState() const { return mSwizzleState; } getSamplerState()134 const SamplerState &getSamplerState() const { return mSamplerState; } getUsage()135 GLenum getUsage() const { return mUsage; } getDepthStencilTextureMode()136 GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; } isStencilMode()137 bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; } 138 139 // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures. 140 const ImageDesc &getBaseLevelDesc() const; 141 142 // GLES1 emulation: For GL_OES_draw_texture 143 void setCrop(const gl::Rectangle &rect); 144 const gl::Rectangle &getCrop() const; 145 146 // GLES1 emulation: Auto-mipmap generation is a texparameter 147 void setGenerateMipmapHint(GLenum hint); 148 GLenum getGenerateMipmapHint() const; 149 150 private: 151 // Texture needs access to the ImageDesc functions. 152 friend class Texture; 153 // TODO(jmadill): Remove TextureGL from friends. 154 friend class rx::TextureGL; 155 friend bool operator==(const TextureState &a, const TextureState &b); 156 157 bool computeSamplerCompleteness(const SamplerState &samplerState, const State &data) const; 158 bool computeMipmapCompleteness() const; 159 bool computeLevelCompleteness(TextureTarget target, size_t level) const; 160 SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const; 161 162 TextureTarget getBaseImageTarget() const; 163 164 void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc); 165 void setImageDescChain(GLuint baselevel, 166 GLuint maxLevel, 167 Extents baseSize, 168 const Format &format, 169 InitState initState); 170 void setImageDescChainMultisample(Extents baseSize, 171 const Format &format, 172 GLsizei samples, 173 bool fixedSampleLocations, 174 InitState initState); 175 176 void clearImageDesc(TextureTarget target, size_t level); 177 void clearImageDescs(); 178 179 const TextureType mType; 180 181 SwizzleState mSwizzleState; 182 183 SamplerState mSamplerState; 184 185 GLuint mBaseLevel; 186 GLuint mMaxLevel; 187 188 GLenum mDepthStencilTextureMode; 189 190 bool mImmutableFormat; 191 GLuint mImmutableLevels; 192 193 // From GL_ANGLE_texture_usage 194 GLenum mUsage; 195 196 std::vector<ImageDesc> mImageDescs; 197 198 // GLES1 emulation: Texture crop rectangle 199 // For GL_OES_draw_texture 200 gl::Rectangle mCropRect; 201 202 // GLES1 emulation: Generate-mipmap hint per texture 203 GLenum mGenerateMipmapHint; 204 205 InitState mInitState; 206 207 mutable SamplerFormat mCachedSamplerFormat; 208 mutable GLenum mCachedSamplerCompareMode; 209 mutable bool mCachedSamplerFormatValid; 210 }; 211 212 bool operator==(const TextureState &a, const TextureState &b); 213 bool operator!=(const TextureState &a, const TextureState &b); 214 215 class Texture final : public RefCountObject, public egl::ImageSibling, public LabeledObject 216 { 217 public: 218 Texture(rx::GLImplFactory *factory, TextureID id, TextureType type); 219 ~Texture() override; 220 221 void onDestroy(const Context *context) override; 222 223 void setLabel(const Context *context, const std::string &label) override; 224 const std::string &getLabel() const override; 225 getType()226 TextureType getType() const { return mState.mType; } 227 228 void setSwizzleRed(const Context *context, GLenum swizzleRed); 229 GLenum getSwizzleRed() const; 230 231 void setSwizzleGreen(const Context *context, GLenum swizzleGreen); 232 GLenum getSwizzleGreen() const; 233 234 void setSwizzleBlue(const Context *context, GLenum swizzleBlue); 235 GLenum getSwizzleBlue() const; 236 237 void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha); 238 GLenum getSwizzleAlpha() const; 239 240 void setMinFilter(const Context *context, GLenum minFilter); 241 GLenum getMinFilter() const; 242 243 void setMagFilter(const Context *context, GLenum magFilter); 244 GLenum getMagFilter() const; 245 246 void setWrapS(const Context *context, GLenum wrapS); 247 GLenum getWrapS() const; 248 249 void setWrapT(const Context *context, GLenum wrapT); 250 GLenum getWrapT() const; 251 252 void setWrapR(const Context *context, GLenum wrapR); 253 GLenum getWrapR() const; 254 255 void setMaxAnisotropy(const Context *context, float maxAnisotropy); 256 float getMaxAnisotropy() const; 257 258 void setMinLod(const Context *context, GLfloat minLod); 259 GLfloat getMinLod() const; 260 261 void setMaxLod(const Context *context, GLfloat maxLod); 262 GLfloat getMaxLod() const; 263 264 void setCompareMode(const Context *context, GLenum compareMode); 265 GLenum getCompareMode() const; 266 267 void setCompareFunc(const Context *context, GLenum compareFunc); 268 GLenum getCompareFunc() const; 269 270 void setSRGBDecode(const Context *context, GLenum sRGBDecode); 271 GLenum getSRGBDecode() const; 272 273 const SamplerState &getSamplerState() const; 274 275 angle::Result setBaseLevel(const Context *context, GLuint baseLevel); 276 GLuint getBaseLevel() const; 277 278 void setMaxLevel(const Context *context, GLuint maxLevel); 279 GLuint getMaxLevel() const; 280 281 void setDepthStencilTextureMode(const Context *context, GLenum mode); 282 GLenum getDepthStencilTextureMode() const; 283 284 bool getImmutableFormat() const; 285 286 GLuint getImmutableLevels() const; 287 288 void setUsage(const Context *context, GLenum usage); 289 GLenum getUsage() const; 290 291 void setBorderColor(const Context *context, const ColorGeneric &color); 292 const ColorGeneric &getBorderColor() const; 293 294 const TextureState &getTextureState() const; 295 296 size_t getWidth(TextureTarget target, size_t level) const; 297 size_t getHeight(TextureTarget target, size_t level) const; 298 size_t getDepth(TextureTarget target, size_t level) const; 299 GLsizei getSamples(TextureTarget target, size_t level) const; 300 bool getFixedSampleLocations(TextureTarget target, size_t level) const; 301 const Format &getFormat(TextureTarget target, size_t level) const; 302 303 // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. 304 GLuint getMipmapMaxLevel() const; 305 306 bool isMipmapComplete() const; 307 308 angle::Result setImage(Context *context, 309 const PixelUnpackState &unpackState, 310 TextureTarget target, 311 GLint level, 312 GLenum internalFormat, 313 const Extents &size, 314 GLenum format, 315 GLenum type, 316 const uint8_t *pixels); 317 angle::Result setSubImage(Context *context, 318 const PixelUnpackState &unpackState, 319 Buffer *unpackBuffer, 320 TextureTarget target, 321 GLint level, 322 const Box &area, 323 GLenum format, 324 GLenum type, 325 const uint8_t *pixels); 326 327 angle::Result setCompressedImage(Context *context, 328 const PixelUnpackState &unpackState, 329 TextureTarget target, 330 GLint level, 331 GLenum internalFormat, 332 const Extents &size, 333 size_t imageSize, 334 const uint8_t *pixels); 335 angle::Result setCompressedSubImage(const Context *context, 336 const PixelUnpackState &unpackState, 337 TextureTarget target, 338 GLint level, 339 const Box &area, 340 GLenum format, 341 size_t imageSize, 342 const uint8_t *pixels); 343 344 angle::Result copyImage(Context *context, 345 TextureTarget target, 346 GLint level, 347 const Rectangle &sourceArea, 348 GLenum internalFormat, 349 Framebuffer *source); 350 angle::Result copySubImage(Context *context, 351 const ImageIndex &index, 352 const Offset &destOffset, 353 const Rectangle &sourceArea, 354 Framebuffer *source); 355 356 angle::Result copyTexture(Context *context, 357 TextureTarget target, 358 GLint level, 359 GLenum internalFormat, 360 GLenum type, 361 GLint sourceLevel, 362 bool unpackFlipY, 363 bool unpackPremultiplyAlpha, 364 bool unpackUnmultiplyAlpha, 365 Texture *source); 366 angle::Result copySubTexture(const Context *context, 367 TextureTarget target, 368 GLint level, 369 const Offset &destOffset, 370 GLint sourceLevel, 371 const Box &sourceBox, 372 bool unpackFlipY, 373 bool unpackPremultiplyAlpha, 374 bool unpackUnmultiplyAlpha, 375 Texture *source); 376 angle::Result copyCompressedTexture(Context *context, const Texture *source); 377 378 angle::Result setStorage(Context *context, 379 TextureType type, 380 GLsizei levels, 381 GLenum internalFormat, 382 const Extents &size); 383 384 angle::Result setStorageMultisample(Context *context, 385 TextureType type, 386 GLsizei samples, 387 GLint internalformat, 388 const Extents &size, 389 bool fixedSampleLocations); 390 391 angle::Result setStorageExternalMemory(Context *context, 392 TextureType type, 393 GLsizei levels, 394 GLenum internalFormat, 395 const Extents &size, 396 MemoryObject *memoryObject, 397 GLuint64 offset); 398 399 angle::Result setImageExternal(Context *context, 400 TextureTarget target, 401 GLint level, 402 GLenum internalFormat, 403 const Extents &size, 404 GLenum format, 405 GLenum type); 406 407 angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget); 408 409 angle::Result generateMipmap(Context *context); 410 411 egl::Surface *getBoundSurface() const; 412 egl::Stream *getBoundStream() const; 413 414 GLint getMemorySize() const; 415 GLint getLevelMemorySize(TextureTarget target, GLint level) const; 416 417 void signalDirtyStorage(InitState initState); 418 419 bool isSamplerComplete(const Context *context, const Sampler *optionalSampler); 420 getImplementation()421 rx::TextureImpl *getImplementation() const { return mTexture; } 422 423 // FramebufferAttachmentObject implementation 424 Extents getAttachmentSize(const ImageIndex &imageIndex) const override; 425 Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; 426 GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override; 427 bool isRenderable(const Context *context, 428 GLenum binding, 429 const ImageIndex &imageIndex) const override; 430 431 bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const; 432 433 // GLES1 emulation 434 void setCrop(const gl::Rectangle &rect); 435 const gl::Rectangle &getCrop() const; 436 void setGenerateMipmapHint(GLenum generate); 437 GLenum getGenerateMipmapHint() const; 438 439 void onAttach(const Context *context) override; 440 void onDetach(const Context *context) override; 441 GLuint getId() const override; 442 GLuint getNativeID() const; 443 444 // Needed for robust resource init. 445 angle::Result ensureInitialized(const Context *context); 446 InitState initState(const ImageIndex &imageIndex) const override; initState()447 InitState initState() const { return mState.mInitState; } 448 void setInitState(const ImageIndex &imageIndex, InitState initState) override; 449 450 enum DirtyBitType 451 { 452 // Sampler state 453 DIRTY_BIT_MIN_FILTER, 454 DIRTY_BIT_MAG_FILTER, 455 DIRTY_BIT_WRAP_S, 456 DIRTY_BIT_WRAP_T, 457 DIRTY_BIT_WRAP_R, 458 DIRTY_BIT_MAX_ANISOTROPY, 459 DIRTY_BIT_MIN_LOD, 460 DIRTY_BIT_MAX_LOD, 461 DIRTY_BIT_COMPARE_MODE, 462 DIRTY_BIT_COMPARE_FUNC, 463 DIRTY_BIT_SRGB_DECODE, 464 DIRTY_BIT_BORDER_COLOR, 465 466 // Texture state 467 DIRTY_BIT_SWIZZLE_RED, 468 DIRTY_BIT_SWIZZLE_GREEN, 469 DIRTY_BIT_SWIZZLE_BLUE, 470 DIRTY_BIT_SWIZZLE_ALPHA, 471 DIRTY_BIT_BASE_LEVEL, 472 DIRTY_BIT_MAX_LEVEL, 473 DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE, 474 475 // Misc 476 DIRTY_BIT_LABEL, 477 DIRTY_BIT_USAGE, 478 DIRTY_BIT_IMPLEMENTATION, 479 480 DIRTY_BIT_COUNT, 481 }; 482 using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; 483 484 angle::Result syncState(const Context *context); hasAnyDirtyBit()485 bool hasAnyDirtyBit() const { return mDirtyBits.any(); } 486 487 // ObserverInterface implementation. 488 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 489 490 private: 491 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 492 493 // ANGLE-only method, used internally 494 friend class egl::Surface; 495 angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface); 496 angle::Result releaseTexImageFromSurface(const Context *context); 497 498 // ANGLE-only methods, used internally 499 friend class egl::Stream; 500 void bindStream(egl::Stream *stream); 501 void releaseStream(); 502 angle::Result acquireImageFromStream(const Context *context, 503 const egl::Stream::GLTextureDescription &desc); 504 angle::Result releaseImageFromStream(const Context *context); 505 506 void invalidateCompletenessCache() const; 507 angle::Result releaseTexImageInternal(Context *context); 508 509 angle::Result ensureSubImageInitialized(const Context *context, 510 TextureTarget target, 511 size_t level, 512 const gl::Box &area); 513 514 angle::Result handleMipmapGenerationHint(Context *context, int level); 515 516 void signalDirtyState(size_t dirtyBit); 517 518 TextureState mState; 519 DirtyBits mDirtyBits; 520 rx::TextureImpl *mTexture; 521 angle::ObserverBinding mImplObserver; 522 523 std::string mLabel; 524 525 egl::Surface *mBoundSurface; 526 egl::Stream *mBoundStream; 527 528 struct SamplerCompletenessCache 529 { 530 SamplerCompletenessCache(); 531 532 // Context used to generate this cache entry 533 ContextID context; 534 535 // All values that affect sampler completeness that are not stored within 536 // the texture itself 537 SamplerState samplerState; 538 539 // Result of the sampler completeness with the above parameters 540 bool samplerComplete; 541 }; 542 543 mutable SamplerCompletenessCache mCompletenessCache; 544 }; 545 546 inline bool operator==(const TextureState &a, const TextureState &b) 547 { 548 return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState && 549 a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel && 550 a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels && 551 a.mUsage == b.mUsage; 552 } 553 554 inline bool operator!=(const TextureState &a, const TextureState &b) 555 { 556 return !(a == b); 557 } 558 } // namespace gl 559 560 #endif // LIBANGLE_TEXTURE_H_ 561