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