texture_manager.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_ 6#define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_ 7 8#include <list> 9#include <string> 10#include <vector> 11#include "base/basictypes.h" 12#include "base/hash_tables.h" 13#include "base/logging.h" 14#include "base/memory/ref_counted.h" 15#include "gpu/command_buffer/service/gl_utils.h" 16#include "gpu/command_buffer/service/memory_tracking.h" 17#include "gpu/gpu_export.h" 18#include "ui/gl/async_pixel_transfer_delegate.h" 19#include "ui/gl/gl_image.h" 20 21namespace gpu { 22namespace gles2 { 23 24class GLES2Decoder; 25class Display; 26class FeatureInfo; 27class TextureDefinition; 28class TextureManager; 29 30// Info about Textures currently in the system. 31class GPU_EXPORT Texture : public base::RefCounted<Texture> { 32 public: 33 Texture(TextureManager* manager, GLuint service_id); 34 35 GLenum min_filter() const { 36 return min_filter_; 37 } 38 39 GLenum mag_filter() const { 40 return mag_filter_; 41 } 42 43 GLenum wrap_s() const { 44 return wrap_s_; 45 } 46 47 GLenum wrap_t() const { 48 return wrap_t_; 49 } 50 51 GLenum usage() const { 52 return usage_; 53 } 54 55 GLenum pool() const { 56 return pool_; 57 } 58 59 int num_uncleared_mips() const { 60 return num_uncleared_mips_; 61 } 62 63 uint32 estimated_size() const { 64 return estimated_size_; 65 } 66 67 bool CanRenderTo() const { 68 return !stream_texture_ && target_ != GL_TEXTURE_EXTERNAL_OES; 69 } 70 71 // The service side OpenGL id of the texture. 72 GLuint service_id() const { 73 return service_id_; 74 } 75 76 void SetServiceId(GLuint service_id) { 77 service_id_ = service_id; 78 } 79 80 // Returns the target this texure was first bound to or 0 if it has not 81 // been bound. Once a texture is bound to a specific target it can never be 82 // bound to a different target. 83 GLenum target() const { 84 return target_; 85 } 86 87 // In GLES2 "texture complete" means it has all required mips for filtering 88 // down to a 1x1 pixel texture, they are in the correct order, they are all 89 // the same format. 90 bool texture_complete() const { 91 return texture_complete_; 92 } 93 94 // In GLES2 "cube complete" means all 6 faces level 0 are defined, all the 95 // same format, all the same dimensions and all width = height. 96 bool cube_complete() const { 97 return cube_complete_; 98 } 99 100 // Whether or not this texture is a non-power-of-two texture. 101 bool npot() const { 102 return npot_; 103 } 104 105 bool SafeToRenderFrom() const { 106 return cleared_; 107 } 108 109 // Get the width and height for a particular level. Returns false if level 110 // does not exist. 111 bool GetLevelSize( 112 GLint target, GLint level, GLsizei* width, GLsizei* height) const; 113 114 // Get the type of a level. Returns false if level does not exist. 115 bool GetLevelType( 116 GLint target, GLint level, GLenum* type, GLenum* internal_format) const; 117 118 // Get the image bound to a particular level. Returns NULL if level 119 // does not exist. 120 gfx::GLImage* GetLevelImage(GLint target, GLint level) const; 121 122 bool IsDeleted() const { 123 return deleted_; 124 } 125 126 // Returns true of the given dimensions are inside the dimensions of the 127 // level and if the format and type match the level. 128 bool ValidForTexture( 129 GLint target, 130 GLint level, 131 GLint xoffset, 132 GLint yoffset, 133 GLsizei width, 134 GLsizei height, 135 GLenum format, 136 GLenum type) const; 137 138 bool IsValid() const { 139 return target() && !IsDeleted(); 140 } 141 142 void SetNotOwned() { 143 owned_ = false; 144 } 145 146 bool IsAttachedToFramebuffer() const { 147 return framebuffer_attachment_count_ != 0; 148 } 149 150 void AttachToFramebuffer() { 151 ++framebuffer_attachment_count_; 152 } 153 154 void DetachFromFramebuffer() { 155 DCHECK_GT(framebuffer_attachment_count_, 0); 156 --framebuffer_attachment_count_; 157 } 158 159 void SetStreamTexture(bool stream_texture) { 160 stream_texture_ = stream_texture; 161 } 162 163 int IsStreamTexture() { 164 return stream_texture_; 165 } 166 167 gfx::AsyncPixelTransferState* GetAsyncTransferState() const { 168 return async_transfer_state_.get(); 169 } 170 void SetAsyncTransferState(scoped_ptr<gfx::AsyncPixelTransferState> state) { 171 async_transfer_state_ = state.Pass(); 172 } 173 bool AsyncTransferIsInProgress() { 174 return async_transfer_state_ && 175 async_transfer_state_->TransferIsInProgress(); 176 } 177 178 void SetImmutable(bool immutable) { 179 immutable_ = immutable; 180 } 181 182 bool IsImmutable() { 183 return immutable_; 184 } 185 186 // Whether a particular level/face is cleared. 187 bool IsLevelCleared(GLenum target, GLint level) const; 188 189 // Whether the texture has been defined 190 bool IsDefined() { 191 return estimated_size() > 0; 192 } 193 194 private: 195 friend class TextureManager; 196 friend class base::RefCounted<Texture>; 197 198 ~Texture(); 199 200 struct LevelInfo { 201 LevelInfo(); 202 LevelInfo(const LevelInfo& rhs); 203 ~LevelInfo(); 204 205 bool cleared; 206 GLenum target; 207 GLint level; 208 GLenum internal_format; 209 GLsizei width; 210 GLsizei height; 211 GLsizei depth; 212 GLint border; 213 GLenum format; 214 GLenum type; 215 scoped_refptr<gfx::GLImage> image; 216 uint32 estimated_size; 217 }; 218 219 // Set the info for a particular level. 220 void SetLevelInfo( 221 const FeatureInfo* feature_info, 222 GLenum target, 223 GLint level, 224 GLenum internal_format, 225 GLsizei width, 226 GLsizei height, 227 GLsizei depth, 228 GLint border, 229 GLenum format, 230 GLenum type, 231 bool cleared); 232 233 // Marks a particular level as cleared or uncleared. 234 void SetLevelCleared(GLenum target, GLint level, bool cleared); 235 236 // Updates the cleared flag for this texture by inspecting all the mips. 237 void UpdateCleared(); 238 239 // Clears any renderable uncleared levels. 240 // Returns false if a GL error was generated. 241 bool ClearRenderableLevels(GLES2Decoder* decoder); 242 243 // Clears the level. 244 // Returns false if a GL error was generated. 245 bool ClearLevel(GLES2Decoder* decoder, GLenum target, GLint level); 246 247 // Sets a texture parameter. 248 // TODO(gman): Expand to SetParameteri,f,iv,fv 249 // Returns GL_NO_ERROR on success. Otherwise the error to generate. 250 GLenum SetParameter( 251 const FeatureInfo* feature_info, GLenum pname, GLint param); 252 253 // Makes each of the mip levels as though they were generated. 254 bool MarkMipmapsGenerated(const FeatureInfo* feature_info); 255 256 void MarkAsDeleted() { 257 deleted_ = true; 258 } 259 260 bool NeedsMips() const { 261 return min_filter_ != GL_NEAREST && min_filter_ != GL_LINEAR; 262 } 263 264 // True if this texture meets all the GLES2 criteria for rendering. 265 // See section 3.8.2 of the GLES2 spec. 266 bool CanRender(const FeatureInfo* feature_info) const; 267 268 // Returns true if mipmaps can be generated by GL. 269 bool CanGenerateMipmaps(const FeatureInfo* feature_info) const; 270 271 // Sets the Texture's target 272 // Parameters: 273 // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP or 274 // GL_TEXTURE_EXTERNAL_OES or GL_TEXTURE_RECTANGLE_ARB 275 // max_levels: The maximum levels this type of target can have. 276 void SetTarget(GLenum target, GLint max_levels); 277 278 // Update info about this texture. 279 void Update(const FeatureInfo* feature_info); 280 281 // Set the image for a particular level. 282 void SetLevelImage( 283 const FeatureInfo* feature_info, 284 GLenum target, 285 GLint level, 286 gfx::GLImage* image); 287 288 // Appends a signature for the given level. 289 void AddToSignature( 290 const FeatureInfo* feature_info, 291 GLenum target, GLint level, std::string* signature) const; 292 293 // Info about each face and level of texture. 294 std::vector<std::vector<LevelInfo> > level_infos_; 295 296 // The texture manager that manages this Texture. 297 TextureManager* manager_; 298 299 // The id of the texure 300 GLuint service_id_; 301 302 // Whether this texture has been deleted. 303 bool deleted_; 304 305 // Whether all renderable mips of this texture have been cleared. 306 bool cleared_; 307 308 int num_uncleared_mips_; 309 310 // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP. 311 GLenum target_; 312 313 // Texture parameters. 314 GLenum min_filter_; 315 GLenum mag_filter_; 316 GLenum wrap_s_; 317 GLenum wrap_t_; 318 GLenum usage_; 319 GLenum pool_; 320 321 // The maximum level that has been set. 322 GLint max_level_set_; 323 324 // Whether or not this texture is "texture complete" 325 bool texture_complete_; 326 327 // Whether or not this texture is "cube complete" 328 bool cube_complete_; 329 330 // Whether or not this texture is non-power-of-two 331 bool npot_; 332 333 // Whether this texture has ever been bound. 334 bool has_been_bound_; 335 336 // The number of framebuffers this texture is attached to. 337 int framebuffer_attachment_count_; 338 339 // Whether the associated context group owns this texture and should delete 340 // it. 341 bool owned_; 342 343 // Whether this is a special streaming texture. 344 bool stream_texture_; 345 346 // State to facilitate async transfers on this texture. 347 scoped_ptr<gfx::AsyncPixelTransferState> async_transfer_state_; 348 349 // Whether the texture is immutable and no further changes to the format 350 // or dimensions of the texture object can be made. 351 bool immutable_; 352 353 // Size in bytes this texture is assumed to take in memory. 354 uint32 estimated_size_; 355 356 DISALLOW_COPY_AND_ASSIGN(Texture); 357}; 358 359// This class keeps track of the textures and their sizes so we can do NPOT and 360// texture complete checking. 361// 362// NOTE: To support shared resources an instance of this class will need to be 363// shared by multiple GLES2Decoders. 364class GPU_EXPORT TextureManager { 365 public: 366 enum DefaultAndBlackTextures { 367 kTexture2D, 368 kCubeMap, 369 kExternalOES, 370 kRectangleARB, 371 kNumDefaultTextures 372 }; 373 374 TextureManager(MemoryTracker* memory_tracker, 375 FeatureInfo* feature_info, 376 GLsizei max_texture_size, 377 GLsizei max_cube_map_texture_size); 378 ~TextureManager(); 379 380 // Init the texture manager. 381 bool Initialize(); 382 383 // Must call before destruction. 384 void Destroy(bool have_context); 385 386 // Returns the maximum number of levels. 387 GLint MaxLevelsForTarget(GLenum target) const { 388 switch (target) { 389 case GL_TEXTURE_2D: 390 return max_levels_; 391 case GL_TEXTURE_EXTERNAL_OES: 392 return 1; 393 default: 394 return max_cube_map_levels_; 395 } 396 } 397 398 // Returns the maximum size. 399 GLsizei MaxSizeForTarget(GLenum target) const { 400 switch (target) { 401 case GL_TEXTURE_2D: 402 case GL_TEXTURE_EXTERNAL_OES: 403 return max_texture_size_; 404 default: 405 return max_cube_map_texture_size_; 406 } 407 } 408 409 // Returns the maxium number of levels a texture of the given size can have. 410 static GLsizei ComputeMipMapCount( 411 GLsizei width, GLsizei height, GLsizei depth); 412 413 // Checks if a dimensions are valid for a given target. 414 bool ValidForTarget( 415 GLenum target, GLint level, 416 GLsizei width, GLsizei height, GLsizei depth); 417 418 // True if this texture meets all the GLES2 criteria for rendering. 419 // See section 3.8.2 of the GLES2 spec. 420 bool CanRender(const Texture* texture) const { 421 return texture->CanRender(feature_info_); 422 } 423 424 // Returns true if mipmaps can be generated by GL. 425 bool CanGenerateMipmaps(const Texture* texture) const { 426 return texture->CanGenerateMipmaps(feature_info_); 427 } 428 429 // Sets the Texture's target 430 // Parameters: 431 // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP 432 // max_levels: The maximum levels this type of target can have. 433 void SetTarget( 434 Texture* texture, 435 GLenum target); 436 437 // Set the info for a particular level in a TexureInfo. 438 void SetLevelInfo( 439 Texture* texture, 440 GLenum target, 441 GLint level, 442 GLenum internal_format, 443 GLsizei width, 444 GLsizei height, 445 GLsizei depth, 446 GLint border, 447 GLenum format, 448 GLenum type, 449 bool cleared); 450 451 // Adapter to call above function. 452 void SetLevelInfoFromParams(Texture* texture, 453 const gfx::AsyncTexImage2DParams& params) { 454 SetLevelInfo( 455 texture, params.target, params.level, params.internal_format, 456 params.width, params.height, 1 /* depth */, 457 params.border, params.format, 458 params.type, true /* cleared */ ); 459 } 460 461 // Save the texture definition and leave it undefined. 462 TextureDefinition* Save(Texture* texture); 463 464 // Redefine all the levels from the texture definition. 465 bool Restore( 466 const char* function_name, 467 GLES2Decoder* decoder, 468 Texture* texture, 469 TextureDefinition* definition); 470 471 // Sets a mip as cleared. 472 void SetLevelCleared(Texture* texture, GLenum target, 473 GLint level, bool cleared); 474 475 // Sets a texture parameter of a Texture 476 // Returns GL_NO_ERROR on success. Otherwise the error to generate. 477 // TODO(gman): Expand to SetParameteri,f,iv,fv 478 void SetParameter( 479 const char* function_name, GLES2Decoder* decoder, 480 Texture* texture, GLenum pname, GLint param); 481 482 // Makes each of the mip levels as though they were generated. 483 // Returns false if that's not allowed for the given texture. 484 bool MarkMipmapsGenerated(Texture* texture); 485 486 // Clears any uncleared renderable levels. 487 bool ClearRenderableLevels(GLES2Decoder* decoder, Texture* texture); 488 489 // Clear a specific level. 490 bool ClearTextureLevel( 491 GLES2Decoder* decoder,Texture* texture, GLenum target, GLint level); 492 493 // Creates a new texture info. 494 Texture* CreateTexture(GLuint client_id, GLuint service_id); 495 496 // Gets the texture info for the given texture. 497 Texture* GetTexture(GLuint client_id) const; 498 499 // Removes a texture info. 500 void RemoveTexture(GLuint client_id); 501 502 // Gets a client id for a given service id. 503 bool GetClientId(GLuint service_id, GLuint* client_id) const; 504 505 Texture* GetDefaultTextureInfo(GLenum target) { 506 switch (target) { 507 case GL_TEXTURE_2D: 508 return default_textures_[kTexture2D]; 509 case GL_TEXTURE_CUBE_MAP: 510 return default_textures_[kCubeMap]; 511 case GL_TEXTURE_EXTERNAL_OES: 512 return default_textures_[kExternalOES]; 513 case GL_TEXTURE_RECTANGLE_ARB: 514 return default_textures_[kRectangleARB]; 515 default: 516 NOTREACHED(); 517 return NULL; 518 } 519 } 520 521 bool HaveUnrenderableTextures() const { 522 return num_unrenderable_textures_ > 0; 523 } 524 525 bool HaveUnsafeTextures() const { 526 return num_unsafe_textures_ > 0; 527 } 528 529 bool HaveUnclearedMips() const { 530 return num_uncleared_mips_ > 0; 531 } 532 533 GLuint black_texture_id(GLenum target) const { 534 switch (target) { 535 case GL_SAMPLER_2D: 536 return black_texture_ids_[kTexture2D]; 537 case GL_SAMPLER_CUBE: 538 return black_texture_ids_[kCubeMap]; 539 case GL_SAMPLER_EXTERNAL_OES: 540 return black_texture_ids_[kExternalOES]; 541 case GL_SAMPLER_2D_RECT_ARB: 542 return black_texture_ids_[kRectangleARB]; 543 default: 544 NOTREACHED(); 545 return 0; 546 } 547 } 548 549 size_t mem_represented() const { 550 return 551 memory_tracker_managed_->GetMemRepresented() + 552 memory_tracker_unmanaged_->GetMemRepresented(); 553 } 554 555 void SetLevelImage( 556 Texture* texture, 557 GLenum target, 558 GLint level, 559 gfx::GLImage* image); 560 561 void AddToSignature( 562 Texture* texture, 563 GLenum target, 564 GLint level, 565 std::string* signature) const; 566 567 private: 568 friend class Texture; 569 570 // Helper for Initialize(). 571 scoped_refptr<Texture> CreateDefaultAndBlackTextures( 572 GLenum target, 573 GLuint* black_texture); 574 575 void StartTracking(Texture* texture); 576 void StopTracking(Texture* texture); 577 578 MemoryTypeTracker* GetMemTracker(GLenum texture_pool); 579 scoped_ptr<MemoryTypeTracker> memory_tracker_managed_; 580 scoped_ptr<MemoryTypeTracker> memory_tracker_unmanaged_; 581 582 scoped_refptr<FeatureInfo> feature_info_; 583 584 // Info for each texture in the system. 585 typedef base::hash_map<GLuint, scoped_refptr<Texture> > TextureMap; 586 TextureMap textures_; 587 588 GLsizei max_texture_size_; 589 GLsizei max_cube_map_texture_size_; 590 GLint max_levels_; 591 GLint max_cube_map_levels_; 592 593 int num_unrenderable_textures_; 594 int num_unsafe_textures_; 595 int num_uncleared_mips_; 596 597 // Counts the number of Textures allocated with 'this' as its manager. 598 // Allows to check no Texture will outlive this. 599 unsigned int texture_count_; 600 601 bool have_context_; 602 603 // Black (0,0,0,1) textures for when non-renderable textures are used. 604 // NOTE: There is no corresponding Texture for these textures. 605 // TextureInfos are only for textures the client side can access. 606 GLuint black_texture_ids_[kNumDefaultTextures]; 607 608 // The default textures for each target (texture name = 0) 609 scoped_refptr<Texture> default_textures_[kNumDefaultTextures]; 610 611 DISALLOW_COPY_AND_ASSIGN(TextureManager); 612}; 613 614} // namespace gles2 615} // namespace gpu 616 617#endif // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_ 618