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_RENDERBUFFER_MANAGER_H_
6#define GPU_COMMAND_BUFFER_SERVICE_RENDERBUFFER_MANAGER_H_
7
8#include <string>
9#include "base/basictypes.h"
10#include "base/containers/hash_tables.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "gpu/command_buffer/service/gl_utils.h"
14#include "gpu/command_buffer/service/memory_tracking.h"
15#include "gpu/gpu_export.h"
16
17namespace gpu {
18namespace gles2 {
19
20class RenderbufferManager;
21
22// Info about a Renderbuffer.
23class GPU_EXPORT Renderbuffer
24    : public base::RefCounted<Renderbuffer> {
25 public:
26  Renderbuffer(RenderbufferManager* manager,
27               GLuint client_id,
28               GLuint service_id);
29
30  GLuint service_id() const {
31    return service_id_;
32  }
33
34  GLuint client_id() const {
35    return client_id_;
36  }
37
38  bool cleared() const {
39    return cleared_;
40  }
41
42  GLenum internal_format() const {
43    return internal_format_;
44  }
45
46  GLsizei samples() const {
47    return samples_;
48  }
49
50  GLsizei width() const {
51    return width_;
52  }
53
54  GLsizei height() const {
55    return height_;
56  }
57
58  bool IsDeleted() const {
59    return client_id_ == 0;
60  }
61
62  void MarkAsValid() {
63    has_been_bound_ = true;
64  }
65
66  bool IsValid() const {
67    return has_been_bound_ && !IsDeleted();
68  }
69
70  size_t EstimatedSize();
71
72  void AddToSignature(std::string* signature) const;
73
74 private:
75  friend class RenderbufferManager;
76  friend class base::RefCounted<Renderbuffer>;
77
78  ~Renderbuffer();
79
80  void set_cleared(bool cleared) {
81    cleared_ = cleared;
82  }
83
84  void SetInfo(
85      GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
86    samples_ = samples;
87    internal_format_ = internalformat;
88    width_ = width;
89    height_ = height;
90    cleared_ = false;
91  }
92
93  void MarkAsDeleted() {
94    client_id_ = 0;
95  }
96
97  // RenderbufferManager that owns this Renderbuffer.
98  RenderbufferManager* manager_;
99
100  // Client side renderbuffer id.
101  GLuint client_id_;
102
103  // Service side renderbuffer id.
104  GLuint service_id_;
105
106  // Whether this renderbuffer has been cleared
107  bool cleared_;
108
109  // Whether this renderbuffer has ever been bound.
110  bool has_been_bound_;
111
112  // Number of samples (for multi-sampled renderbuffers)
113  GLsizei samples_;
114
115  // Renderbuffer internalformat set through RenderbufferStorage().
116  GLenum internal_format_;
117
118  // Dimensions of renderbuffer.
119  GLsizei width_;
120  GLsizei height_;
121};
122
123// This class keeps track of the renderbuffers and whether or not they have
124// been cleared.
125class GPU_EXPORT RenderbufferManager {
126 public:
127  RenderbufferManager(MemoryTracker* memory_tracker,
128                      GLint max_renderbuffer_size,
129                      GLint max_samples,
130                      bool depth24_supported);
131  ~RenderbufferManager();
132
133  GLint max_renderbuffer_size() const {
134    return max_renderbuffer_size_;
135  }
136
137  GLint max_samples() const {
138    return max_samples_;
139  }
140
141  bool HaveUnclearedRenderbuffers() const {
142    return num_uncleared_renderbuffers_ != 0;
143  }
144
145  void SetInfo(
146      Renderbuffer* renderbuffer,
147      GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
148
149  void SetCleared(Renderbuffer* renderbuffer, bool cleared);
150
151  // Must call before destruction.
152  void Destroy(bool have_context);
153
154  // Creates a Renderbuffer for the given renderbuffer ids.
155  void CreateRenderbuffer(GLuint client_id, GLuint service_id);
156
157  // Gets the renderbuffer for the given renderbuffer id.
158  Renderbuffer* GetRenderbuffer(GLuint client_id);
159
160  // Removes a renderbuffer for the given renderbuffer id.
161  void RemoveRenderbuffer(GLuint client_id);
162
163  size_t mem_represented() const {
164    return memory_tracker_->GetMemRepresented();
165  }
166
167  bool ComputeEstimatedRenderbufferSize(int width,
168                                        int height,
169                                        int samples,
170                                        int internal_format,
171                                        uint32* size) const;
172  GLenum InternalRenderbufferFormatToImplFormat(GLenum impl_format) const;
173
174 private:
175  friend class Renderbuffer;
176
177  void StartTracking(Renderbuffer* renderbuffer);
178  void StopTracking(Renderbuffer* renderbuffer);
179
180  scoped_ptr<MemoryTypeTracker> memory_tracker_;
181
182  GLint max_renderbuffer_size_;
183  GLint max_samples_;
184  bool depth24_supported_;
185
186  int num_uncleared_renderbuffers_;
187
188  // Counts the number of Renderbuffer allocated with 'this' as its manager.
189  // Allows to check no Renderbuffer will outlive this.
190  unsigned renderbuffer_count_;
191
192  bool have_context_;
193
194  // Info for each renderbuffer in the system.
195  typedef base::hash_map<GLuint, scoped_refptr<Renderbuffer> > RenderbufferMap;
196  RenderbufferMap renderbuffers_;
197
198  DISALLOW_COPY_AND_ASSIGN(RenderbufferManager);
199};
200
201}  // namespace gles2
202}  // namespace gpu
203
204#endif  // GPU_COMMAND_BUFFER_SERVICE_RENDERBUFFER_MANAGER_H_
205