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