blob: 7f20e973d18b1464a440a047c4b90503f03dd779 [file] [log] [blame]
// Copyright (c) 2016 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/transform_feedback_manager.h"
#include "gpu/command_buffer/service/buffer_manager.h"
#include "ui/gl/gl_version_info.h"
namespace gpu {
namespace gles2 {
TransformFeedback::TransformFeedback(TransformFeedbackManager* manager,
GLuint client_id,
GLuint service_id)
: IndexedBufferBindingHost(
manager->max_transform_feedback_separate_attribs(),
manager->needs_emulation()),
manager_(manager),
client_id_(client_id),
service_id_(service_id),
has_been_bound_(false),
active_(false),
paused_(false),
primitive_mode_(GL_NONE) {
DCHECK_LE(0u, client_id);
DCHECK_LT(0u, service_id);
}
TransformFeedback::~TransformFeedback() {
if (!manager_->lost_context()) {
if (active_)
glEndTransformFeedback();
glDeleteTransformFeedbacks(1, &service_id_);
}
}
void TransformFeedback::DoBindTransformFeedback(GLenum target) {
DCHECK_LT(0u, service_id_);
glBindTransformFeedback(target, service_id_);
has_been_bound_ = true;
OnBindHost(target);
if (active_ && !paused_) {
// This could only happen during virtual context switching.
// Otherwise the validation should generate a GL error without calling
// into this function.
glResumeTransformFeedback();
}
}
void TransformFeedback::DoBeginTransformFeedback(GLenum primitive_mode) {
DCHECK(!active_);
DCHECK(primitive_mode == GL_POINTS ||
primitive_mode == GL_LINES ||
primitive_mode == GL_TRIANGLES);
glBeginTransformFeedback(primitive_mode);
active_ = true;
primitive_mode_ = primitive_mode;
}
void TransformFeedback::DoEndTransformFeedback() {
DCHECK(active_);
glEndTransformFeedback();
active_ = false;
paused_ = false;
}
void TransformFeedback::DoPauseTransformFeedback() {
DCHECK(active_ && !paused_);
glPauseTransformFeedback();
paused_ = true;
}
void TransformFeedback::DoResumeTransformFeedback() {
DCHECK(active_ && paused_);
glResumeTransformFeedback();
paused_ = false;
}
TransformFeedbackManager::TransformFeedbackManager(
GLuint max_transform_feedback_separate_attribs, bool needs_emulation)
: max_transform_feedback_separate_attribs_(
max_transform_feedback_separate_attribs),
needs_emulation_(needs_emulation),
lost_context_(false) {
DCHECK(needs_emulation);
}
TransformFeedbackManager::~TransformFeedbackManager() {
DCHECK(transform_feedbacks_.empty());
}
void TransformFeedbackManager::Destroy() {
transform_feedbacks_.clear();
}
TransformFeedback* TransformFeedbackManager::CreateTransformFeedback(
GLuint client_id, GLuint service_id) {
scoped_refptr<TransformFeedback> transform_feedback(
new TransformFeedback(this, client_id, service_id));
auto result = transform_feedbacks_.insert(
std::make_pair(client_id, transform_feedback));
DCHECK(result.second);
return result.first->second.get();
}
TransformFeedback* TransformFeedbackManager::GetTransformFeedback(
GLuint client_id) {
if (client_id == 0) {
return nullptr;
}
auto it = transform_feedbacks_.find(client_id);
return it != transform_feedbacks_.end() ? it->second.get() : nullptr;
}
void TransformFeedbackManager::RemoveTransformFeedback(GLuint client_id) {
if (client_id) {
transform_feedbacks_.erase(client_id);
}
}
} // namespace gles2
} // namespace gpu