mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
173 lines
5.2 KiB
C++
173 lines
5.2 KiB
C++
// 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.
|
|
|
|
#include "gpu/command_buffer/service/gl_utils.h"
|
|
#include "gpu/command_buffer/service/program_manager.h"
|
|
#include "gpu/command_buffer/service/valuebuffer_manager.h"
|
|
|
|
namespace gpu {
|
|
namespace gles2 {
|
|
|
|
SubscriptionRefSet::Observer::~Observer() {
|
|
}
|
|
|
|
SubscriptionRefSet::SubscriptionRefSet() {
|
|
}
|
|
|
|
SubscriptionRefSet::~SubscriptionRefSet() {
|
|
// Make sure no valuebuffers are still holding references to targets
|
|
DCHECK(reference_set_.empty());
|
|
}
|
|
|
|
void SubscriptionRefSet::AddSubscription(unsigned int target) {
|
|
RefSet::iterator it = reference_set_.find(target);
|
|
if (it == reference_set_.end()) {
|
|
reference_set_.insert(std::make_pair(target, 1));
|
|
FOR_EACH_OBSERVER(Observer, observers_, OnAddSubscription(target));
|
|
} else {
|
|
++it->second;
|
|
}
|
|
}
|
|
|
|
void SubscriptionRefSet::RemoveSubscription(unsigned int target) {
|
|
RefSet::iterator it = reference_set_.find(target);
|
|
DCHECK(it != reference_set_.end());
|
|
if (it->second == 1) {
|
|
reference_set_.erase(it);
|
|
FOR_EACH_OBSERVER(Observer, observers_, OnRemoveSubscription(target));
|
|
} else {
|
|
--it->second;
|
|
}
|
|
}
|
|
|
|
void SubscriptionRefSet::AddObserver(Observer* observer) {
|
|
observers_.AddObserver(observer);
|
|
}
|
|
|
|
void SubscriptionRefSet::RemoveObserver(Observer* observer) {
|
|
observers_.RemoveObserver(observer);
|
|
}
|
|
|
|
Valuebuffer::Valuebuffer(ValuebufferManager* manager, unsigned int client_id)
|
|
: manager_(manager), client_id_(client_id), has_been_bound_(false) {
|
|
manager_->StartTracking(this);
|
|
active_state_map_ = new ValueStateMap();
|
|
}
|
|
|
|
Valuebuffer::~Valuebuffer() {
|
|
if (manager_) {
|
|
for (SubscriptionSet::const_iterator it = subscriptions_.begin();
|
|
it != subscriptions_.end(); ++it) {
|
|
manager_->NotifyRemoveSubscription(*it);
|
|
}
|
|
manager_->StopTracking(this);
|
|
manager_ = NULL;
|
|
}
|
|
}
|
|
|
|
void Valuebuffer::AddSubscription(unsigned int subscription) {
|
|
if (subscriptions_.find(subscription) == subscriptions_.end()) {
|
|
subscriptions_.insert(subscription);
|
|
manager_->NotifyAddSubscription(subscription);
|
|
}
|
|
}
|
|
|
|
void Valuebuffer::RemoveSubscription(unsigned int subscription) {
|
|
SubscriptionSet::iterator it = subscriptions_.find(subscription);
|
|
if (subscriptions_.find(subscription) != subscriptions_.end()) {
|
|
subscriptions_.erase(it);
|
|
manager_->NotifyRemoveSubscription(subscription);
|
|
}
|
|
}
|
|
|
|
bool Valuebuffer::IsSubscribed(unsigned int subscription) {
|
|
return subscriptions_.find(subscription) != subscriptions_.end();
|
|
}
|
|
|
|
const ValueState* Valuebuffer::GetState(unsigned int target) const {
|
|
return active_state_map_->GetState(target);
|
|
}
|
|
|
|
void Valuebuffer::UpdateState(const ValueStateMap* pending_state) {
|
|
DCHECK(pending_state);
|
|
for (SubscriptionSet::const_iterator it = subscriptions_.begin();
|
|
it != subscriptions_.end(); ++it) {
|
|
const ValueState *state = pending_state->GetState(*it);
|
|
if (state != NULL) {
|
|
active_state_map_->UpdateState(*it, *state);
|
|
}
|
|
}
|
|
}
|
|
|
|
ValuebufferManager::ValuebufferManager(SubscriptionRefSet* ref_set,
|
|
ValueStateMap* state_map)
|
|
: valuebuffer_count_(0),
|
|
pending_state_map_(state_map),
|
|
subscription_ref_set_(ref_set) {
|
|
}
|
|
|
|
ValuebufferManager::~ValuebufferManager() {
|
|
DCHECK(valuebuffer_map_.empty());
|
|
// If this triggers, that means something is keeping a reference to
|
|
// a Valuebuffer belonging to this.
|
|
CHECK_EQ(valuebuffer_count_, 0u);
|
|
}
|
|
|
|
void ValuebufferManager::Destroy() {
|
|
valuebuffer_map_.clear();
|
|
}
|
|
|
|
void ValuebufferManager::StartTracking(Valuebuffer* /* valuebuffer */) {
|
|
++valuebuffer_count_;
|
|
}
|
|
|
|
void ValuebufferManager::StopTracking(Valuebuffer* /* valuebuffer */) {
|
|
--valuebuffer_count_;
|
|
}
|
|
|
|
void ValuebufferManager::NotifyAddSubscription(unsigned int target) {
|
|
subscription_ref_set_->AddSubscription(target);
|
|
}
|
|
void ValuebufferManager::NotifyRemoveSubscription(unsigned int target) {
|
|
subscription_ref_set_->RemoveSubscription(target);
|
|
}
|
|
|
|
void ValuebufferManager::CreateValuebuffer(unsigned int client_id) {
|
|
scoped_refptr<Valuebuffer> valuebuffer(new Valuebuffer(this, client_id));
|
|
std::pair<ValuebufferMap::iterator, bool> result =
|
|
valuebuffer_map_.insert(std::make_pair(client_id, valuebuffer));
|
|
DCHECK(result.second);
|
|
}
|
|
|
|
Valuebuffer* ValuebufferManager::GetValuebuffer(unsigned int client_id) {
|
|
ValuebufferMap::iterator it = valuebuffer_map_.find(client_id);
|
|
return it != valuebuffer_map_.end() ? it->second.get() : NULL;
|
|
}
|
|
|
|
void ValuebufferManager::RemoveValuebuffer(unsigned int client_id) {
|
|
ValuebufferMap::iterator it = valuebuffer_map_.find(client_id);
|
|
if (it != valuebuffer_map_.end()) {
|
|
Valuebuffer* valuebuffer = it->second.get();
|
|
valuebuffer->MarkAsDeleted();
|
|
valuebuffer_map_.erase(it);
|
|
}
|
|
}
|
|
|
|
void ValuebufferManager::UpdateValuebufferState(Valuebuffer* valuebuffer) {
|
|
DCHECK(valuebuffer);
|
|
valuebuffer->UpdateState(pending_state_map_.get());
|
|
}
|
|
|
|
uint32 ValuebufferManager::ApiTypeForSubscriptionTarget(unsigned int target) {
|
|
switch (target) {
|
|
case GL_MOUSE_POSITION_CHROMIUM:
|
|
return Program::kUniform2i;
|
|
}
|
|
NOTREACHED() << "Unhandled uniform subscription target " << target;
|
|
return Program::kUniformNone;
|
|
}
|
|
|
|
} // namespace gles2
|
|
} // namespace gpu
|