summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service/valuebuffer_manager.h
blob: 3cc4ac194a8a5ac73eb08dffe9cb34347c9419b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_COMMAND_BUFFER_SERVICE_VALUEBUFFER_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_VALUEBUFFER_MANAGER_H_

#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/gpu_export.h"

namespace gpu {
namespace gles2 {

class ValuebufferManager;

union ValueState {
  float float_value[4];
  int int_value[4];
};

class GPU_EXPORT Valuebuffer : public base::RefCounted<Valuebuffer> {
 public:
  Valuebuffer(ValuebufferManager* manager, GLuint client_id);

  GLuint client_id() const { return client_id_; }

  bool IsDeleted() const { return client_id_ == 0; }

  void MarkAsValid() { has_been_bound_ = true; }

  bool IsValid() const { return has_been_bound_ && !IsDeleted(); }

  void AddSubscription(GLenum subscription);
  void RemoveSubscription(GLenum subscription);

  // Returns true if this Valuebuffer is subscribed to subscription
  bool IsSubscribed(GLenum subscription);

  // Returns the active state for a given target in this Valuebuffer
  // returns NULL if target state doesn't exist
  const ValueState* GetState(GLenum target) const;

 private:
  friend class ValuebufferManager;
  friend class base::RefCounted<Valuebuffer>;

  typedef base::hash_map<GLenum, ValueState> StateMap;
  typedef base::hash_set<GLenum> SubscriptionSet;

  ~Valuebuffer();

  void UpdateState(const StateMap& pending_state);

  void MarkAsDeleted() { client_id_ = 0; }

  // ValuebufferManager that owns this Valuebuffer.
  ValuebufferManager* manager_;

  // Client side Valuebuffer id.
  GLuint client_id_;

  // Whether this Valuebuffer has ever been bound.
  bool has_been_bound_;

  SubscriptionSet subscriptions_;

  StateMap active_state_map_;
};

class GPU_EXPORT ValuebufferManager {
 public:
  ValuebufferManager();
  ~ValuebufferManager();

  // Must call before destruction.
  void Destroy();

  // Creates a Valuebuffer for the given Valuebuffer ids.
  void CreateValuebuffer(GLuint client_id);

  // Gets the Valuebuffer for the given Valuebuffer id.
  Valuebuffer* GetValuebuffer(GLuint client_id);

  // Removes a Valuebuffer for the given Valuebuffer id.
  void RemoveValuebuffer(GLuint client_id);

  // Updates the value state for the given Valuebuffer
  void UpdateValuebufferState(Valuebuffer* valuebuffer);

  // Gets the state for the given subscription target
  void UpdateValueState(GLenum target, const ValueState& state);

  static uint32 ApiTypeForSubscriptionTarget(GLenum target);

 private:
  friend class Valuebuffer;

  typedef base::hash_map<GLuint, scoped_refptr<Valuebuffer>> ValuebufferMap;

  void StartTracking(Valuebuffer* valuebuffer);
  void StopTracking(Valuebuffer* valuebuffer);

  // Counts the number of Valuebuffer allocated with 'this' as its manager.
  // Allows to check no Valuebuffer will outlive this.
  unsigned valuebuffer_count_;

  // Info for each Valuebuffer in the system.
  ValuebufferMap valuebuffer_map_;

  // Current value state in the system
  Valuebuffer::StateMap pending_state_map_;

  DISALLOW_COPY_AND_ASSIGN(ValuebufferManager);
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_VALUEBUFFER_MANAGER_H_