1 // Copyright (c) 2014 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 #include "gpu/command_buffer/service/gl_utils.h"
6 #include "gpu/command_buffer/service/program_manager.h"
7 #include "gpu/command_buffer/service/valuebuffer_manager.h"
12 SubscriptionRefSet::Observer::~Observer() {
15 SubscriptionRefSet::SubscriptionRefSet() {
18 SubscriptionRefSet::~SubscriptionRefSet() {
19 // Make sure no valuebuffers are still holding references to targets
20 DCHECK(reference_set_
.empty());
23 void SubscriptionRefSet::AddSubscription(unsigned int target
) {
24 RefSet::iterator it
= reference_set_
.find(target
);
25 if (it
== reference_set_
.end()) {
26 reference_set_
.insert(std::make_pair(target
, 1));
27 FOR_EACH_OBSERVER(Observer
, observers_
, OnAddSubscription(target
));
33 void SubscriptionRefSet::RemoveSubscription(unsigned int target
) {
34 RefSet::iterator it
= reference_set_
.find(target
);
35 DCHECK(it
!= reference_set_
.end());
36 if (it
->second
== 1) {
37 reference_set_
.erase(it
);
38 FOR_EACH_OBSERVER(Observer
, observers_
, OnRemoveSubscription(target
));
44 void SubscriptionRefSet::AddObserver(Observer
* observer
) {
45 observers_
.AddObserver(observer
);
48 void SubscriptionRefSet::RemoveObserver(Observer
* observer
) {
49 observers_
.RemoveObserver(observer
);
52 Valuebuffer::Valuebuffer(ValuebufferManager
* manager
, unsigned int client_id
)
53 : manager_(manager
), client_id_(client_id
), has_been_bound_(false) {
54 manager_
->StartTracking(this);
55 active_state_map_
= new ValueStateMap();
58 Valuebuffer::~Valuebuffer() {
60 for (SubscriptionSet::const_iterator it
= subscriptions_
.begin();
61 it
!= subscriptions_
.end(); ++it
) {
62 manager_
->NotifyRemoveSubscription(*it
);
64 manager_
->StopTracking(this);
69 void Valuebuffer::AddSubscription(unsigned int subscription
) {
70 if (subscriptions_
.find(subscription
) == subscriptions_
.end()) {
71 subscriptions_
.insert(subscription
);
72 manager_
->NotifyAddSubscription(subscription
);
76 void Valuebuffer::RemoveSubscription(unsigned int subscription
) {
77 SubscriptionSet::iterator it
= subscriptions_
.find(subscription
);
78 if (subscriptions_
.find(subscription
) != subscriptions_
.end()) {
79 subscriptions_
.erase(it
);
80 manager_
->NotifyRemoveSubscription(subscription
);
84 bool Valuebuffer::IsSubscribed(unsigned int subscription
) {
85 return subscriptions_
.find(subscription
) != subscriptions_
.end();
88 const ValueState
* Valuebuffer::GetState(unsigned int target
) const {
89 return active_state_map_
->GetState(target
);
92 void Valuebuffer::UpdateState(const ValueStateMap
* pending_state
) {
93 DCHECK(pending_state
);
94 for (SubscriptionSet::const_iterator it
= subscriptions_
.begin();
95 it
!= subscriptions_
.end(); ++it
) {
96 const ValueState
*state
= pending_state
->GetState(*it
);
98 active_state_map_
->UpdateState(*it
, *state
);
103 ValuebufferManager::ValuebufferManager(SubscriptionRefSet
* ref_set
,
104 ValueStateMap
* state_map
)
105 : valuebuffer_count_(0),
106 pending_state_map_(state_map
),
107 subscription_ref_set_(ref_set
) {
110 ValuebufferManager::~ValuebufferManager() {
111 DCHECK(valuebuffer_map_
.empty());
112 // If this triggers, that means something is keeping a reference to
113 // a Valuebuffer belonging to this.
114 CHECK_EQ(valuebuffer_count_
, 0u);
117 void ValuebufferManager::Destroy() {
118 valuebuffer_map_
.clear();
121 void ValuebufferManager::StartTracking(Valuebuffer
* /* valuebuffer */) {
122 ++valuebuffer_count_
;
125 void ValuebufferManager::StopTracking(Valuebuffer
* /* valuebuffer */) {
126 --valuebuffer_count_
;
129 void ValuebufferManager::NotifyAddSubscription(unsigned int target
) {
130 subscription_ref_set_
->AddSubscription(target
);
132 void ValuebufferManager::NotifyRemoveSubscription(unsigned int target
) {
133 subscription_ref_set_
->RemoveSubscription(target
);
136 void ValuebufferManager::CreateValuebuffer(unsigned int client_id
) {
137 scoped_refptr
<Valuebuffer
> valuebuffer(new Valuebuffer(this, client_id
));
138 std::pair
<ValuebufferMap::iterator
, bool> result
=
139 valuebuffer_map_
.insert(std::make_pair(client_id
, valuebuffer
));
140 DCHECK(result
.second
);
143 Valuebuffer
* ValuebufferManager::GetValuebuffer(unsigned int client_id
) {
144 ValuebufferMap::iterator it
= valuebuffer_map_
.find(client_id
);
145 return it
!= valuebuffer_map_
.end() ? it
->second
.get() : NULL
;
148 void ValuebufferManager::RemoveValuebuffer(unsigned int client_id
) {
149 ValuebufferMap::iterator it
= valuebuffer_map_
.find(client_id
);
150 if (it
!= valuebuffer_map_
.end()) {
151 Valuebuffer
* valuebuffer
= it
->second
.get();
152 valuebuffer
->MarkAsDeleted();
153 valuebuffer_map_
.erase(it
);
157 void ValuebufferManager::UpdateValuebufferState(Valuebuffer
* valuebuffer
) {
159 valuebuffer
->UpdateState(pending_state_map_
.get());
162 uint32
ValuebufferManager::ApiTypeForSubscriptionTarget(unsigned int target
) {
164 case GL_MOUSE_POSITION_CHROMIUM
:
165 return Program::kUniform2i
;
167 NOTREACHED() << "Unhandled uniform subscription target " << target
;
168 return Program::kUniformNone
;