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 MailboxManager
;
169 friend class MailboxManagerTest
;
170 friend class TextureDefinition
;
171 friend class TextureManager
;
172 friend class TextureRef
;
173 friend class TextureTestHelper
;
176 void AddTextureRef(TextureRef
* ref
);
177 void RemoveTextureRef(TextureRef
* ref
, bool have_context
);
178 MemoryTypeTracker
* GetMemTracker();
180 // Condition on which this texture is renderable. Can be ONLY_IF_NPOT if it
181 // depends on context support for non-power-of-two textures (i.e. will be
182 // renderable if NPOT support is in the context, otherwise not, e.g. texture
183 // with a NPOT level). ALWAYS means it doesn't depend on context features
184 // (e.g. complete POT), NEVER means it's not renderable regardless (e.g.
186 enum CanRenderCondition
{
189 CAN_RENDER_ONLY_IF_NPOT
194 LevelInfo(const LevelInfo
& rhs
);
200 GLenum internal_format
;
207 scoped_refptr
<gfx::GLImage
> image
;
208 uint32 estimated_size
;
211 // Set the info for a particular level.
213 const FeatureInfo
* feature_info
,
216 GLenum internal_format
,
225 // In GLES2 "texture complete" means it has all required mips for filtering
226 // down to a 1x1 pixel texture, they are in the correct order, they are all
228 bool texture_complete() const {
229 return texture_complete_
;
232 // In GLES2 "cube complete" means all 6 faces level 0 are defined, all the
233 // same format, all the same dimensions and all width = height.
234 bool cube_complete() const {
235 return cube_complete_
;
238 // Whether or not this texture is a non-power-of-two texture.
243 // Marks a particular level as cleared or uncleared.
244 void SetLevelCleared(GLenum target
, GLint level
, bool cleared
);
246 // Updates the cleared flag for this texture by inspecting all the mips.
247 void UpdateCleared();
249 // Clears any renderable uncleared levels.
250 // Returns false if a GL error was generated.
251 bool ClearRenderableLevels(GLES2Decoder
* decoder
);
254 // Returns false if a GL error was generated.
255 bool ClearLevel(GLES2Decoder
* decoder
, GLenum target
, GLint level
);
257 // Sets a texture parameter.
258 // TODO(gman): Expand to SetParameteriv,fv
259 // Returns GL_NO_ERROR on success. Otherwise the error to generate.
260 GLenum
SetParameteri(
261 const FeatureInfo
* feature_info
, GLenum pname
, GLint param
);
262 GLenum
SetParameterf(
263 const FeatureInfo
* feature_info
, GLenum pname
, GLfloat param
);
265 // Makes each of the mip levels as though they were generated.
266 bool MarkMipmapsGenerated(const FeatureInfo
* feature_info
);
268 bool NeedsMips() const {
269 return min_filter_
!= GL_NEAREST
&& min_filter_
!= GL_LINEAR
;
272 // True if this texture meets all the GLES2 criteria for rendering.
273 // See section 3.8.2 of the GLES2 spec.
274 bool CanRender(const FeatureInfo
* feature_info
) const;
276 // Returns true if mipmaps can be generated by GL.
277 bool CanGenerateMipmaps(const FeatureInfo
* feature_info
) const;
279 // Sets the Texture's target
281 // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP or
282 // GL_TEXTURE_EXTERNAL_OES or GL_TEXTURE_RECTANGLE_ARB
283 // max_levels: The maximum levels this type of target can have.
285 const FeatureInfo
* feature_info
, GLenum target
, GLint max_levels
);
287 // Update info about this texture.
288 void Update(const FeatureInfo
* feature_info
);
290 // Set the image for a particular level.
292 const FeatureInfo
* feature_info
,
295 gfx::GLImage
* image
);
297 // Appends a signature for the given level.
299 const FeatureInfo
* feature_info
,
300 GLenum target
, GLint level
, std::string
* signature
) const;
302 void SetMailboxManager(MailboxManager
* mailbox_manager
);
304 // Updates the unsafe textures count in all the managers referencing this
306 void UpdateSafeToRenderFrom(bool cleared
);
308 // Updates the uncleared mip count in all the managers referencing this
310 void UpdateMipCleared(LevelInfo
* info
, bool cleared
);
312 // Computes the CanRenderCondition flag.
313 CanRenderCondition
GetCanRenderCondition() const;
315 // Updates the unrenderable texture count in all the managers referencing this
317 void UpdateCanRenderCondition();
319 // Updates the images count in all the managers referencing this
321 void UpdateHasImages();
323 // Increment the framebuffer state change count in all the managers
324 // referencing this texture.
325 void IncAllFramebufferStateChangeCount();
327 MailboxManager
* mailbox_manager_
;
329 // Info about each face and level of texture.
330 std::vector
<std::vector
<LevelInfo
> > level_infos_
;
332 // The texture refs that point to this Texture.
333 typedef std::set
<TextureRef
*> RefSet
;
336 // The single TextureRef that accounts for memory for this texture. Must be
338 TextureRef
* memory_tracking_ref_
;
340 // The id of the texure
343 // Whether all renderable mips of this texture have been cleared.
346 int num_uncleared_mips_
;
348 // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
351 // Texture parameters.
359 // The maximum level that has been set.
360 GLint max_level_set_
;
362 // Whether or not this texture is "texture complete"
363 bool texture_complete_
;
365 // Whether or not this texture is "cube complete"
368 // Whether or not this texture is non-power-of-two
371 // Whether this texture has ever been bound.
372 bool has_been_bound_
;
374 // The number of framebuffers this texture is attached to.
375 int framebuffer_attachment_count_
;
377 // Whether the texture is immutable and no further changes to the format
378 // or dimensions of the texture object can be made.
381 // Whether or not this texture has images.
384 // Size in bytes this texture is assumed to take in memory.
385 uint32 estimated_size_
;
387 // Cache of the computed CanRenderCondition flag.
388 CanRenderCondition can_render_condition_
;
390 // Whether we have initialized TEXTURE_MAX_ANISOTROPY to 1.
391 bool texture_max_anisotropy_initialized_
;
393 DISALLOW_COPY_AND_ASSIGN(Texture
);
396 // This class represents a texture in a client context group. It's mostly 1:1
397 // with a client id, though it can outlive the client id if it's still bound to
398 // a FBO or another context when destroyed.
399 // Multiple TextureRef can point to the same texture with cross-context sharing.
400 class GPU_EXPORT TextureRef
: public base::RefCounted
<TextureRef
> {
402 TextureRef(TextureManager
* manager
, GLuint client_id
, Texture
* texture
);
403 static scoped_refptr
<TextureRef
> Create(TextureManager
* manager
,
407 void AddObserver() { num_observers_
++; }
408 void RemoveObserver() { num_observers_
--; }
410 const Texture
* texture() const { return texture_
; }
411 Texture
* texture() { return texture_
; }
412 GLuint
client_id() const { return client_id_
; }
413 GLuint
service_id() const { return texture_
->service_id(); }
414 GLint
num_observers() const { return num_observers_
; }
417 friend class base::RefCounted
<TextureRef
>;
418 friend class Texture
;
419 friend class TextureManager
;
422 const TextureManager
* manager() const { return manager_
; }
423 TextureManager
* manager() { return manager_
; }
424 void reset_client_id() { client_id_
= 0; }
426 TextureManager
* manager_
;
429 GLint num_observers_
;
431 DISALLOW_COPY_AND_ASSIGN(TextureRef
);
434 // Holds data that is per gles2_cmd_decoder, but is related to to the
436 struct DecoderTextureState
{
437 // total_texture_upload_time automatically initialized to 0 in default
439 explicit DecoderTextureState(bool texsubimage2d_faster_than_teximage2d
)
440 : tex_image_2d_failed(false),
441 texture_upload_count(0),
442 texsubimage2d_faster_than_teximage2d(
443 texsubimage2d_faster_than_teximage2d
) {}
445 // This indicates all the following texSubImage2D calls that are part of the
446 // failed texImage2D call should be ignored.
447 bool tex_image_2d_failed
;
449 // Command buffer stats.
450 int texture_upload_count
;
451 base::TimeDelta total_texture_upload_time
;
453 bool texsubimage2d_faster_than_teximage2d
;
456 // This class keeps track of the textures and their sizes so we can do NPOT and
457 // texture complete checking.
459 // NOTE: To support shared resources an instance of this class will need to be
460 // shared by multiple GLES2Decoders.
461 class GPU_EXPORT TextureManager
{
463 class GPU_EXPORT DestructionObserver
{
465 DestructionObserver();
466 virtual ~DestructionObserver();
468 // Called in ~TextureManager.
469 virtual void OnTextureManagerDestroying(TextureManager
* manager
) = 0;
471 // Called via ~TextureRef.
472 virtual void OnTextureRefDestroying(TextureRef
* texture
) = 0;
475 DISALLOW_COPY_AND_ASSIGN(DestructionObserver
);
478 enum DefaultAndBlackTextures
{
486 TextureManager(MemoryTracker
* memory_tracker
,
487 FeatureInfo
* feature_info
,
488 GLsizei max_texture_size
,
489 GLsizei max_cube_map_texture_size
,
490 bool use_default_textures
);
493 void set_framebuffer_manager(FramebufferManager
* manager
) {
494 framebuffer_manager_
= manager
;
497 // Init the texture manager.
500 // Must call before destruction.
501 void Destroy(bool have_context
);
503 // Returns the maximum number of levels.
504 GLint
MaxLevelsForTarget(GLenum target
) const {
508 case GL_TEXTURE_EXTERNAL_OES
:
511 return max_cube_map_levels_
;
515 // Returns the maximum size.
516 GLsizei
MaxSizeForTarget(GLenum target
) const {
519 case GL_TEXTURE_EXTERNAL_OES
:
520 return max_texture_size_
;
522 return max_cube_map_texture_size_
;
526 // Returns the maxium number of levels a texture of the given size can have.
527 static GLsizei
ComputeMipMapCount(GLenum target
,
532 // Checks if a dimensions are valid for a given target.
534 GLenum target
, GLint level
,
535 GLsizei width
, GLsizei height
, GLsizei depth
);
537 // True if this texture meets all the GLES2 criteria for rendering.
538 // See section 3.8.2 of the GLES2 spec.
539 bool CanRender(const TextureRef
* ref
) const {
540 return ref
->texture()->CanRender(feature_info_
.get());
543 // Returns true if mipmaps can be generated by GL.
544 bool CanGenerateMipmaps(const TextureRef
* ref
) const {
545 return ref
->texture()->CanGenerateMipmaps(feature_info_
.get());
548 // Sets the Texture's target
550 // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP
551 // max_levels: The maximum levels this type of target can have.
556 // Set the info for a particular level in a TexureInfo.
561 GLenum internal_format
,
570 // Adapter to call above function.
571 void SetLevelInfoFromParams(TextureRef
* ref
,
572 const gpu::AsyncTexImage2DParams
& params
) {
574 ref
, params
.target
, params
.level
, params
.internal_format
,
575 params
.width
, params
.height
, 1 /* depth */,
576 params
.border
, params
.format
,
577 params
.type
, true /* cleared */);
580 Texture
* Produce(TextureRef
* ref
);
582 // Maps an existing texture into the texture manager, at a given client ID.
583 TextureRef
* Consume(GLuint client_id
, Texture
* texture
);
585 // Sets a mip as cleared.
586 void SetLevelCleared(TextureRef
* ref
, GLenum target
,
587 GLint level
, bool cleared
);
589 // Sets a texture parameter of a Texture
590 // Returns GL_NO_ERROR on success. Otherwise the error to generate.
591 // TODO(gman): Expand to SetParameteriv,fv
593 const char* function_name
, ErrorState
* error_state
,
594 TextureRef
* ref
, GLenum pname
, GLint param
);
596 const char* function_name
, ErrorState
* error_state
,
597 TextureRef
* ref
, GLenum pname
, GLfloat param
);
599 // Makes each of the mip levels as though they were generated.
600 // Returns false if that's not allowed for the given texture.
601 bool MarkMipmapsGenerated(TextureRef
* ref
);
603 // Clears any uncleared renderable levels.
604 bool ClearRenderableLevels(GLES2Decoder
* decoder
, TextureRef
* ref
);
606 // Clear a specific level.
607 bool ClearTextureLevel(
608 GLES2Decoder
* decoder
, TextureRef
* ref
, GLenum target
, GLint level
);
610 // Creates a new texture info.
611 TextureRef
* CreateTexture(GLuint client_id
, GLuint service_id
);
613 // Gets the texture info for the given texture.
614 TextureRef
* GetTexture(GLuint client_id
) const;
616 // Removes a texture info.
617 void RemoveTexture(GLuint client_id
);
619 // Gets a Texture for a given service id (note: it assumes the texture object
620 // is still mapped in this TextureManager).
621 Texture
* GetTextureForServiceId(GLuint service_id
) const;
623 TextureRef
* GetDefaultTextureInfo(GLenum target
) {
626 return default_textures_
[kTexture2D
].get();
627 case GL_TEXTURE_CUBE_MAP
:
628 return default_textures_
[kCubeMap
].get();
629 case GL_TEXTURE_EXTERNAL_OES
:
630 return default_textures_
[kExternalOES
].get();
631 case GL_TEXTURE_RECTANGLE_ARB
:
632 return default_textures_
[kRectangleARB
].get();
639 bool HaveUnrenderableTextures() const {
640 return num_unrenderable_textures_
> 0;
643 bool HaveUnsafeTextures() const {
644 return num_unsafe_textures_
> 0;
647 bool HaveUnclearedMips() const {
648 return num_uncleared_mips_
> 0;
651 bool HaveImages() const {
652 return num_images_
> 0;
655 GLuint
black_texture_id(GLenum target
) const {
658 return black_texture_ids_
[kTexture2D
];
659 case GL_SAMPLER_CUBE
:
660 return black_texture_ids_
[kCubeMap
];
661 case GL_SAMPLER_EXTERNAL_OES
:
662 return black_texture_ids_
[kExternalOES
];
663 case GL_SAMPLER_2D_RECT_ARB
:
664 return black_texture_ids_
[kRectangleARB
];
671 size_t mem_represented() const {
673 memory_tracker_managed_
->GetMemRepresented() +
674 memory_tracker_unmanaged_
->GetMemRepresented();
681 gfx::GLImage
* image
);
687 std::string
* signature
) const;
689 void AddObserver(DestructionObserver
* observer
) {
690 destruction_observers_
.push_back(observer
);
693 void RemoveObserver(DestructionObserver
* observer
) {
694 for (unsigned int i
= 0; i
< destruction_observers_
.size(); i
++) {
695 if (destruction_observers_
[i
] == observer
) {
696 std::swap(destruction_observers_
[i
], destruction_observers_
.back());
697 destruction_observers_
.pop_back();
704 struct DoTextImage2DArguments
{
707 GLenum internal_format
;
717 bool ValidateTexImage2D(
719 const char* function_name
,
720 const DoTextImage2DArguments
& args
,
721 // Pointer to TextureRef filled in if validation successful.
722 // Presumes the pointer is valid.
723 TextureRef
** texture_ref
);
725 void ValidateAndDoTexImage2D(
726 DecoderTextureState
* texture_state
,
728 DecoderFramebufferState
* framebuffer_state
,
729 const DoTextImage2DArguments
& args
);
731 // TODO(kloveless): Make GetTexture* private once this is no longer called
732 // from gles2_cmd_decoder.
733 TextureRef
* GetTextureInfoForTarget(ContextState
* state
, GLenum target
);
734 TextureRef
* GetTextureInfoForTargetUnlessDefault(
735 ContextState
* state
, GLenum target
);
737 bool ValidateFormatAndTypeCombination(
738 ErrorState
* error_state
, const char* function_name
,
739 GLenum format
, GLenum type
);
741 // Note that internal_format is only checked in relation to the format
742 // parameter, so that this function may be used to validate texSubImage2D.
743 bool ValidateTextureParameters(
744 ErrorState
* error_state
, const char* function_name
,
745 GLenum format
, GLenum type
, GLenum internal_format
, GLint level
);
748 friend class Texture
;
749 friend class TextureRef
;
751 // Helper for Initialize().
752 scoped_refptr
<TextureRef
> CreateDefaultAndBlackTextures(
754 GLuint
* black_texture
);
757 DecoderTextureState
* texture_state
,
758 ErrorState
* error_state
,
759 DecoderFramebufferState
* framebuffer_state
,
760 TextureRef
* texture_ref
,
761 const DoTextImage2DArguments
& args
);
763 void StartTracking(TextureRef
* texture
);
764 void StopTracking(TextureRef
* texture
);
766 void UpdateSafeToRenderFrom(int delta
);
767 void UpdateUnclearedMips(int delta
);
768 void UpdateCanRenderCondition(Texture::CanRenderCondition old_condition
,
769 Texture::CanRenderCondition new_condition
);
770 void UpdateNumImages(int delta
);
771 void IncFramebufferStateChangeCount();
773 MemoryTypeTracker
* GetMemTracker(GLenum texture_pool
);
774 scoped_ptr
<MemoryTypeTracker
> memory_tracker_managed_
;
775 scoped_ptr
<MemoryTypeTracker
> memory_tracker_unmanaged_
;
777 scoped_refptr
<FeatureInfo
> feature_info_
;
779 FramebufferManager
* framebuffer_manager_
;
781 // Info for each texture in the system.
782 typedef base::hash_map
<GLuint
, scoped_refptr
<TextureRef
> > TextureMap
;
783 TextureMap textures_
;
785 GLsizei max_texture_size_
;
786 GLsizei max_cube_map_texture_size_
;
788 GLint max_cube_map_levels_
;
790 const bool use_default_textures_
;
792 int num_unrenderable_textures_
;
793 int num_unsafe_textures_
;
794 int num_uncleared_mips_
;
797 // Counts the number of Textures allocated with 'this' as its manager.
798 // Allows to check no Texture will outlive this.
799 unsigned int texture_count_
;
803 // Black (0,0,0,1) textures for when non-renderable textures are used.
804 // NOTE: There is no corresponding Texture for these textures.
805 // TextureInfos are only for textures the client side can access.
806 GLuint black_texture_ids_
[kNumDefaultTextures
];
808 // The default textures for each target (texture name = 0)
809 scoped_refptr
<TextureRef
> default_textures_
[kNumDefaultTextures
];
811 std::vector
<DestructionObserver
*> destruction_observers_
;
813 DISALLOW_COPY_AND_ASSIGN(TextureManager
);
816 // This class records texture upload time when in scope.
817 class ScopedTextureUploadTimer
{
819 explicit ScopedTextureUploadTimer(DecoderTextureState
* texture_state
);
820 ~ScopedTextureUploadTimer();
823 DecoderTextureState
* texture_state_
;
824 base::TimeTicks begin_time_
;
825 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer
);
831 #endif // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_