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.
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_
13 #include "base/basictypes.h"
14 #include "base/containers/hash_tables.h"
15 #include "base/memory/ref_counted.h"
16 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
17 #include "gpu/command_buffer/service/gl_utils.h"
18 #include "gpu/command_buffer/service/memory_tracking.h"
19 #include "gpu/gpu_export.h"
20 #include "ui/gl/gl_image.h"
27 struct DecoderFramebufferState
;
31 class FramebufferManager
;
36 // Info about Textures currently in the system.
37 // This class wraps a real GL texture, keeping track of its meta-data. It is
38 // jointly owned by possibly multiple TextureRef.
39 class GPU_EXPORT Texture
{
41 explicit Texture(GLuint service_id
);
43 GLenum
min_filter() const {
47 GLenum
mag_filter() const {
51 GLenum
wrap_s() const {
55 GLenum
wrap_t() const {
59 GLenum
usage() const {
67 int num_uncleared_mips() const {
68 return num_uncleared_mips_
;
71 uint32
estimated_size() const {
72 return estimated_size_
;
75 bool CanRenderTo() const {
76 return target_
!= GL_TEXTURE_EXTERNAL_OES
;
79 // The service side OpenGL id of the texture.
80 GLuint
service_id() const {
84 void SetServiceId(GLuint service_id
) {
86 service_id_
= service_id
;
89 // Returns the target this texure was first bound to or 0 if it has not
90 // been bound. Once a texture is bound to a specific target it can never be
91 // bound to a different target.
92 GLenum
target() const {
96 bool SafeToRenderFrom() const {
100 // Get the width and height for a particular level. Returns false if level
103 GLint target
, GLint level
, GLsizei
* width
, GLsizei
* height
) const;
105 // Get the type of a level. Returns false if level does not exist.
107 GLint target
, GLint level
, GLenum
* type
, GLenum
* internal_format
) const;
109 // Get the image bound to a particular level. Returns NULL if level
111 gfx::GLImage
* GetLevelImage(GLint target
, GLint level
) const;
113 bool HasImages() const {
117 // Returns true of the given dimensions are inside the dimensions of the
118 // level and if the type matches the level.
119 bool ValidForTexture(
128 bool IsValid() const {
132 bool IsAttachedToFramebuffer() const {
133 return framebuffer_attachment_count_
!= 0;
136 void AttachToFramebuffer() {
137 ++framebuffer_attachment_count_
;
140 void DetachFromFramebuffer() {
141 DCHECK_GT(framebuffer_attachment_count_
, 0);
142 --framebuffer_attachment_count_
;
145 void SetImmutable(bool immutable
) {
146 immutable_
= immutable
;
149 bool IsImmutable() const {
153 // Whether a particular level/face is cleared.
154 bool IsLevelCleared(GLenum target
, GLint level
) const;
156 // Whether the texture has been defined
157 bool IsDefined() const {
158 return estimated_size() > 0;
161 // Initialize TEXTURE_MAX_ANISOTROPY to 1 if we haven't done so yet.
162 void InitTextureMaxAnisotropyIfNeeded(GLenum target
);
164 void OnWillModifyPixels();
165 void OnDidModifyPixels();
168 friend class MailboxManagerImpl
;
169 friend class MailboxManagerSync
;
170 friend class MailboxManagerTest
;
171 friend class TextureDefinition
;
172 friend class TextureManager
;
173 friend class TextureRef
;
174 friend class TextureTestHelper
;
177 void AddTextureRef(TextureRef
* ref
);
178 void RemoveTextureRef(TextureRef
* ref
, bool have_context
);
179 MemoryTypeTracker
* GetMemTracker();
181 // Condition on which this texture is renderable. Can be ONLY_IF_NPOT if it
182 // depends on context support for non-power-of-two textures (i.e. will be
183 // renderable if NPOT support is in the context, otherwise not, e.g. texture
184 // with a NPOT level). ALWAYS means it doesn't depend on context features
185 // (e.g. complete POT), NEVER means it's not renderable regardless (e.g.
187 enum CanRenderCondition
{
190 CAN_RENDER_ONLY_IF_NPOT
195 LevelInfo(const LevelInfo
& rhs
);
201 GLenum internal_format
;
208 scoped_refptr
<gfx::GLImage
> image
;
209 uint32 estimated_size
;
216 GLsizei num_mip_levels
;
217 std::vector
<LevelInfo
> level_infos
;
220 // Set the info for a particular level.
222 const FeatureInfo
* feature_info
,
225 GLenum internal_format
,
234 // In GLES2 "texture complete" means it has all required mips for filtering
235 // down to a 1x1 pixel texture, they are in the correct order, they are all
237 bool texture_complete() const {
238 return texture_complete_
;
241 // In GLES2 "cube complete" means all 6 faces level 0 are defined, all the
242 // same format, all the same dimensions and all width = height.
243 bool cube_complete() const {
244 return cube_complete_
;
247 // Whether or not this texture is a non-power-of-two texture.
252 // Marks a particular level as cleared or uncleared.
253 void SetLevelCleared(GLenum target
, GLint level
, bool cleared
);
255 // Updates the cleared flag for this texture by inspecting all the mips.
256 void UpdateCleared();
258 // Clears any renderable uncleared levels.
259 // Returns false if a GL error was generated.
260 bool ClearRenderableLevels(GLES2Decoder
* decoder
);
263 // Returns false if a GL error was generated.
264 bool ClearLevel(GLES2Decoder
* decoder
, GLenum target
, GLint level
);
266 // Sets a texture parameter.
267 // TODO(gman): Expand to SetParameteriv,fv
268 // Returns GL_NO_ERROR on success. Otherwise the error to generate.
269 GLenum
SetParameteri(
270 const FeatureInfo
* feature_info
, GLenum pname
, GLint param
);
271 GLenum
SetParameterf(
272 const FeatureInfo
* feature_info
, GLenum pname
, GLfloat param
);
274 // Makes each of the mip levels as though they were generated.
275 bool MarkMipmapsGenerated(const FeatureInfo
* feature_info
);
277 bool NeedsMips() const {
278 return min_filter_
!= GL_NEAREST
&& min_filter_
!= GL_LINEAR
;
281 // True if this texture meets all the GLES2 criteria for rendering.
282 // See section 3.8.2 of the GLES2 spec.
283 bool CanRender(const FeatureInfo
* feature_info
) const;
285 // Returns true if mipmaps can be generated by GL.
286 bool CanGenerateMipmaps(const FeatureInfo
* feature_info
) const;
288 // Returns true if any of the texture dimensions are not a power of two.
289 static bool TextureIsNPOT(GLsizei width
, GLsizei height
, GLsizei depth
);
291 // Returns true if texture face is complete relative to the first face.
292 static bool TextureFaceComplete(const Texture::LevelInfo
& first_face
,
295 GLenum internal_format
,
302 // Returns true if texture mip level is complete relative to first level.
303 static bool TextureMipComplete(const Texture::LevelInfo
& level0_face
,
306 GLenum internal_format
,
313 // Sets the Texture's target
315 // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP or
316 // GL_TEXTURE_EXTERNAL_OES or GL_TEXTURE_RECTANGLE_ARB
317 // max_levels: The maximum levels this type of target can have.
319 const FeatureInfo
* feature_info
, GLenum target
, GLint max_levels
);
321 // Update info about this texture.
322 void Update(const FeatureInfo
* feature_info
);
324 // Set the image for a particular level.
326 const FeatureInfo
* feature_info
,
329 gfx::GLImage
* image
);
331 // Appends a signature for the given level.
333 const FeatureInfo
* feature_info
,
334 GLenum target
, GLint level
, std::string
* signature
) const;
336 void SetMailboxManager(MailboxManager
* mailbox_manager
);
338 // Updates the unsafe textures count in all the managers referencing this
340 void UpdateSafeToRenderFrom(bool cleared
);
342 // Updates the uncleared mip count in all the managers referencing this
344 void UpdateMipCleared(LevelInfo
* info
, bool cleared
);
346 // Computes the CanRenderCondition flag.
347 CanRenderCondition
GetCanRenderCondition() const;
349 // Updates the unrenderable texture count in all the managers referencing this
351 void UpdateCanRenderCondition();
353 // Updates the images count in all the managers referencing this
355 void UpdateHasImages();
357 // Increment the framebuffer state change count in all the managers
358 // referencing this texture.
359 void IncAllFramebufferStateChangeCount();
361 MailboxManager
* mailbox_manager_
;
363 // Info about each face and level of texture.
364 std::vector
<FaceInfo
> face_infos_
;
366 // The texture refs that point to this Texture.
367 typedef std::set
<TextureRef
*> RefSet
;
370 // The single TextureRef that accounts for memory for this texture. Must be
372 TextureRef
* memory_tracking_ref_
;
374 // The id of the texure
377 // Whether all renderable mips of this texture have been cleared.
380 int num_uncleared_mips_
;
383 // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
386 // Texture parameters.
394 // The maximum level that has been set.
395 GLint max_level_set_
;
397 // Whether or not this texture is "texture complete"
398 bool texture_complete_
;
400 // Whether mip levels have changed and should be reverified.
401 bool texture_mips_dirty_
;
402 bool texture_mips_complete_
;
404 // Whether or not this texture is "cube complete"
407 // Whether any level 0 faces have changed and should be reverified.
408 bool texture_level0_dirty_
;
409 bool texture_level0_complete_
;
411 // Whether or not this texture is non-power-of-two
414 // Whether this texture has ever been bound.
415 bool has_been_bound_
;
417 // The number of framebuffers this texture is attached to.
418 int framebuffer_attachment_count_
;
420 // Whether the texture is immutable and no further changes to the format
421 // or dimensions of the texture object can be made.
424 // Whether or not this texture has images.
427 // Size in bytes this texture is assumed to take in memory.
428 uint32 estimated_size_
;
430 // Cache of the computed CanRenderCondition flag.
431 CanRenderCondition can_render_condition_
;
433 // Whether we have initialized TEXTURE_MAX_ANISOTROPY to 1.
434 bool texture_max_anisotropy_initialized_
;
436 DISALLOW_COPY_AND_ASSIGN(Texture
);
439 // This class represents a texture in a client context group. It's mostly 1:1
440 // with a client id, though it can outlive the client id if it's still bound to
441 // a FBO or another context when destroyed.
442 // Multiple TextureRef can point to the same texture with cross-context sharing.
443 class GPU_EXPORT TextureRef
: public base::RefCounted
<TextureRef
> {
445 TextureRef(TextureManager
* manager
, GLuint client_id
, Texture
* texture
);
446 static scoped_refptr
<TextureRef
> Create(TextureManager
* manager
,
450 void AddObserver() { num_observers_
++; }
451 void RemoveObserver() { num_observers_
--; }
453 const Texture
* texture() const { return texture_
; }
454 Texture
* texture() { return texture_
; }
455 GLuint
client_id() const { return client_id_
; }
456 GLuint
service_id() const { return texture_
->service_id(); }
457 GLint
num_observers() const { return num_observers_
; }
460 friend class base::RefCounted
<TextureRef
>;
461 friend class Texture
;
462 friend class TextureManager
;
465 const TextureManager
* manager() const { return manager_
; }
466 TextureManager
* manager() { return manager_
; }
467 void reset_client_id() { client_id_
= 0; }
469 TextureManager
* manager_
;
472 GLint num_observers_
;
474 DISALLOW_COPY_AND_ASSIGN(TextureRef
);
477 // Holds data that is per gles2_cmd_decoder, but is related to to the
479 struct DecoderTextureState
{
480 // total_texture_upload_time automatically initialized to 0 in default
482 explicit DecoderTextureState(bool texsubimage2d_faster_than_teximage2d
)
483 : tex_image_2d_failed(false),
484 texture_upload_count(0),
485 texsubimage2d_faster_than_teximage2d(
486 texsubimage2d_faster_than_teximage2d
) {}
488 // This indicates all the following texSubImage2D calls that are part of the
489 // failed texImage2D call should be ignored.
490 bool tex_image_2d_failed
;
492 // Command buffer stats.
493 int texture_upload_count
;
494 base::TimeDelta total_texture_upload_time
;
496 bool texsubimage2d_faster_than_teximage2d
;
499 // This class keeps track of the textures and their sizes so we can do NPOT and
500 // texture complete checking.
502 // NOTE: To support shared resources an instance of this class will need to be
503 // shared by multiple GLES2Decoders.
504 class GPU_EXPORT TextureManager
{
506 class GPU_EXPORT DestructionObserver
{
508 DestructionObserver();
509 virtual ~DestructionObserver();
511 // Called in ~TextureManager.
512 virtual void OnTextureManagerDestroying(TextureManager
* manager
) = 0;
514 // Called via ~TextureRef.
515 virtual void OnTextureRefDestroying(TextureRef
* texture
) = 0;
518 DISALLOW_COPY_AND_ASSIGN(DestructionObserver
);
521 enum DefaultAndBlackTextures
{
529 TextureManager(MemoryTracker
* memory_tracker
,
530 FeatureInfo
* feature_info
,
531 GLsizei max_texture_size
,
532 GLsizei max_cube_map_texture_size
,
533 GLsizei max_rectangle_texture_size
,
534 bool use_default_textures
);
537 void set_framebuffer_manager(FramebufferManager
* manager
) {
538 framebuffer_manager_
= manager
;
541 // Init the texture manager.
544 // Must call before destruction.
545 void Destroy(bool have_context
);
547 // Returns the maximum number of levels.
548 GLint
MaxLevelsForTarget(GLenum target
) const {
552 case GL_TEXTURE_EXTERNAL_OES
:
555 return max_cube_map_levels_
;
559 // Returns the maximum size.
560 GLsizei
MaxSizeForTarget(GLenum target
) const {
563 case GL_TEXTURE_EXTERNAL_OES
:
564 return max_texture_size_
;
565 case GL_TEXTURE_RECTANGLE
:
566 return max_rectangle_texture_size_
;
568 return max_cube_map_texture_size_
;
572 // Returns the maxium number of levels a texture of the given size can have.
573 static GLsizei
ComputeMipMapCount(GLenum target
,
578 // Checks if a dimensions are valid for a given target.
580 GLenum target
, GLint level
,
581 GLsizei width
, GLsizei height
, GLsizei depth
);
583 // True if this texture meets all the GLES2 criteria for rendering.
584 // See section 3.8.2 of the GLES2 spec.
585 bool CanRender(const TextureRef
* ref
) const {
586 return ref
->texture()->CanRender(feature_info_
.get());
589 // Returns true if mipmaps can be generated by GL.
590 bool CanGenerateMipmaps(const TextureRef
* ref
) const {
591 return ref
->texture()->CanGenerateMipmaps(feature_info_
.get());
594 // Sets the Texture's target
596 // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP
597 // max_levels: The maximum levels this type of target can have.
602 // Set the info for a particular level in a TexureInfo.
607 GLenum internal_format
,
616 // Adapter to call above function.
617 void SetLevelInfoFromParams(TextureRef
* ref
,
618 const gpu::AsyncTexImage2DParams
& params
) {
620 ref
, params
.target
, params
.level
, params
.internal_format
,
621 params
.width
, params
.height
, 1 /* depth */,
622 params
.border
, params
.format
,
623 params
.type
, true /* cleared */);
626 Texture
* Produce(TextureRef
* ref
);
628 // Maps an existing texture into the texture manager, at a given client ID.
629 TextureRef
* Consume(GLuint client_id
, Texture
* texture
);
631 // Sets a mip as cleared.
632 void SetLevelCleared(TextureRef
* ref
, GLenum target
,
633 GLint level
, bool cleared
);
635 // Sets a texture parameter of a Texture
636 // Returns GL_NO_ERROR on success. Otherwise the error to generate.
637 // TODO(gman): Expand to SetParameteriv,fv
639 const char* function_name
, ErrorState
* error_state
,
640 TextureRef
* ref
, GLenum pname
, GLint param
);
642 const char* function_name
, ErrorState
* error_state
,
643 TextureRef
* ref
, GLenum pname
, GLfloat param
);
645 // Makes each of the mip levels as though they were generated.
646 // Returns false if that's not allowed for the given texture.
647 bool MarkMipmapsGenerated(TextureRef
* ref
);
649 // Clears any uncleared renderable levels.
650 bool ClearRenderableLevels(GLES2Decoder
* decoder
, TextureRef
* ref
);
652 // Clear a specific level.
653 bool ClearTextureLevel(
654 GLES2Decoder
* decoder
, TextureRef
* ref
, GLenum target
, GLint level
);
656 // Creates a new texture info.
657 TextureRef
* CreateTexture(GLuint client_id
, GLuint service_id
);
659 // Gets the texture info for the given texture.
660 TextureRef
* GetTexture(GLuint client_id
) const;
662 // Removes a texture info.
663 void RemoveTexture(GLuint client_id
);
665 // Gets a Texture for a given service id (note: it assumes the texture object
666 // is still mapped in this TextureManager).
667 Texture
* GetTextureForServiceId(GLuint service_id
) const;
669 TextureRef
* GetDefaultTextureInfo(GLenum target
) {
672 return default_textures_
[kTexture2D
].get();
673 case GL_TEXTURE_CUBE_MAP
:
674 return default_textures_
[kCubeMap
].get();
675 case GL_TEXTURE_EXTERNAL_OES
:
676 return default_textures_
[kExternalOES
].get();
677 case GL_TEXTURE_RECTANGLE_ARB
:
678 return default_textures_
[kRectangleARB
].get();
685 bool HaveUnrenderableTextures() const {
686 return num_unrenderable_textures_
> 0;
689 bool HaveUnsafeTextures() const {
690 return num_unsafe_textures_
> 0;
693 bool HaveUnclearedMips() const {
694 return num_uncleared_mips_
> 0;
697 bool HaveImages() const {
698 return num_images_
> 0;
701 GLuint
black_texture_id(GLenum target
) const {
704 return black_texture_ids_
[kTexture2D
];
705 case GL_SAMPLER_CUBE
:
706 return black_texture_ids_
[kCubeMap
];
707 case GL_SAMPLER_EXTERNAL_OES
:
708 return black_texture_ids_
[kExternalOES
];
709 case GL_SAMPLER_2D_RECT_ARB
:
710 return black_texture_ids_
[kRectangleARB
];
717 size_t mem_represented() const {
719 memory_tracker_managed_
->GetMemRepresented() +
720 memory_tracker_unmanaged_
->GetMemRepresented();
727 gfx::GLImage
* image
);
729 size_t GetSignatureSize() const;
735 std::string
* signature
) const;
737 void AddObserver(DestructionObserver
* observer
) {
738 destruction_observers_
.push_back(observer
);
741 void RemoveObserver(DestructionObserver
* observer
) {
742 for (unsigned int i
= 0; i
< destruction_observers_
.size(); i
++) {
743 if (destruction_observers_
[i
] == observer
) {
744 std::swap(destruction_observers_
[i
], destruction_observers_
.back());
745 destruction_observers_
.pop_back();
752 struct DoTextImage2DArguments
{
755 GLenum internal_format
;
765 bool ValidateTexImage2D(
767 const char* function_name
,
768 const DoTextImage2DArguments
& args
,
769 // Pointer to TextureRef filled in if validation successful.
770 // Presumes the pointer is valid.
771 TextureRef
** texture_ref
);
773 void ValidateAndDoTexImage2D(
774 DecoderTextureState
* texture_state
,
776 DecoderFramebufferState
* framebuffer_state
,
777 const DoTextImage2DArguments
& args
);
779 // TODO(kloveless): Make GetTexture* private once this is no longer called
780 // from gles2_cmd_decoder.
781 TextureRef
* GetTextureInfoForTarget(ContextState
* state
, GLenum target
);
782 TextureRef
* GetTextureInfoForTargetUnlessDefault(
783 ContextState
* state
, GLenum target
);
785 bool ValidateFormatAndTypeCombination(
786 ErrorState
* error_state
, const char* function_name
,
787 GLenum format
, GLenum type
);
789 // Note that internal_format is only checked in relation to the format
790 // parameter, so that this function may be used to validate texSubImage2D.
791 bool ValidateTextureParameters(
792 ErrorState
* error_state
, const char* function_name
,
793 GLenum format
, GLenum type
, GLenum internal_format
, GLint level
);
796 friend class Texture
;
797 friend class TextureRef
;
799 // Helper for Initialize().
800 scoped_refptr
<TextureRef
> CreateDefaultAndBlackTextures(
802 GLuint
* black_texture
);
805 DecoderTextureState
* texture_state
,
806 ErrorState
* error_state
,
807 DecoderFramebufferState
* framebuffer_state
,
808 TextureRef
* texture_ref
,
809 const DoTextImage2DArguments
& args
);
811 void StartTracking(TextureRef
* texture
);
812 void StopTracking(TextureRef
* texture
);
814 void UpdateSafeToRenderFrom(int delta
);
815 void UpdateUnclearedMips(int delta
);
816 void UpdateCanRenderCondition(Texture::CanRenderCondition old_condition
,
817 Texture::CanRenderCondition new_condition
);
818 void UpdateNumImages(int delta
);
819 void IncFramebufferStateChangeCount();
821 GLenum
AdjustTexFormat(GLenum format
) const;
823 MemoryTypeTracker
* GetMemTracker(GLenum texture_pool
);
824 scoped_ptr
<MemoryTypeTracker
> memory_tracker_managed_
;
825 scoped_ptr
<MemoryTypeTracker
> memory_tracker_unmanaged_
;
827 scoped_refptr
<FeatureInfo
> feature_info_
;
829 FramebufferManager
* framebuffer_manager_
;
831 // Info for each texture in the system.
832 typedef base::hash_map
<GLuint
, scoped_refptr
<TextureRef
> > TextureMap
;
833 TextureMap textures_
;
835 GLsizei max_texture_size_
;
836 GLsizei max_cube_map_texture_size_
;
837 GLsizei max_rectangle_texture_size_
;
839 GLint max_cube_map_levels_
;
841 const bool use_default_textures_
;
843 int num_unrenderable_textures_
;
844 int num_unsafe_textures_
;
845 int num_uncleared_mips_
;
848 // Counts the number of Textures allocated with 'this' as its manager.
849 // Allows to check no Texture will outlive this.
850 unsigned int texture_count_
;
854 // Black (0,0,0,1) textures for when non-renderable textures are used.
855 // NOTE: There is no corresponding Texture for these textures.
856 // TextureInfos are only for textures the client side can access.
857 GLuint black_texture_ids_
[kNumDefaultTextures
];
859 // The default textures for each target (texture name = 0)
860 scoped_refptr
<TextureRef
> default_textures_
[kNumDefaultTextures
];
862 std::vector
<DestructionObserver
*> destruction_observers_
;
864 DISALLOW_COPY_AND_ASSIGN(TextureManager
);
867 // This class records texture upload time when in scope.
868 class ScopedTextureUploadTimer
{
870 explicit ScopedTextureUploadTimer(DecoderTextureState
* texture_state
);
871 ~ScopedTextureUploadTimer();
874 DecoderTextureState
* texture_state_
;
875 base::TimeTicks begin_time_
;
876 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer
);
882 #endif // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_