blob: 2fe75b76725bd2ecb19685397daf9b76aae21f62 [file] [log] [blame]
// Copyright 2019 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/abstract_texture_impl_shared_context_state.h"
#include <utility>
#include "gpu/command_buffer/service/context_state.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/scoped_binders.h"
#include "ui/gl/scoped_make_current.h"
namespace gpu {
namespace gles2 {
AbstractTextureImplOnSharedContext::AbstractTextureImplOnSharedContext(
GLenum target,
GLenum internal_format,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLenum format,
GLenum type,
gpu::SharedContextState* shared_context_state)
: shared_context_state_(shared_context_state) {
DCHECK(shared_context_state_);
// The calling code which wants to create this abstract texture should have
// already made the shared context current.
DCHECK(shared_context_state_->IsCurrent(nullptr));
// Create a gles2 Texture.
GLuint service_id = 0;
auto* api = gl::g_current_gl_context;
api->glGenTexturesFn(1, &service_id);
gl::ScopedTextureBinder binder(target, service_id);
api->glTexParameteriFn(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
api->glTexParameteriFn(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
api->glTexParameteriFn(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
api->glTexParameteriFn(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_ = new gpu::gles2::Texture(service_id);
texture_->SetLightweightRef();
texture_->SetTarget(target, 1);
texture_->sampler_state_.min_filter = GL_LINEAR;
texture_->sampler_state_.mag_filter = GL_LINEAR;
texture_->sampler_state_.wrap_t = GL_CLAMP_TO_EDGE;
texture_->sampler_state_.wrap_s = GL_CLAMP_TO_EDGE;
gfx::Rect cleared_rect;
texture_->SetLevelInfo(target, 0, internal_format, width, height, depth,
border, format, type, cleared_rect);
texture_->SetImmutable(true);
shared_context_state_->AddContextLostObserver(this);
}
AbstractTextureImplOnSharedContext::~AbstractTextureImplOnSharedContext() {
if (cleanup_cb_)
std::move(cleanup_cb_).Run(this);
// If the shared context is lost, |shared_context_state_| will be null.
if (!shared_context_state_) {
texture_->RemoveLightweightRef(false);
} else {
base::Optional<ui::ScopedMakeCurrent> scoped_make_current;
if (!shared_context_state_->IsCurrent(nullptr)) {
scoped_make_current.emplace(shared_context_state_->context(),
shared_context_state_->surface());
}
texture_->RemoveLightweightRef(true);
shared_context_state_->RemoveContextLostObserver(this);
}
texture_ = nullptr;
}
TextureBase* AbstractTextureImplOnSharedContext::GetTextureBase() const {
return texture_;
}
void AbstractTextureImplOnSharedContext::SetParameteri(GLenum pname,
GLint param) {
NOTIMPLEMENTED();
}
void AbstractTextureImplOnSharedContext::BindStreamTextureImage(
GLStreamTextureImage* image,
GLuint service_id) {
NOTIMPLEMENTED();
}
void AbstractTextureImplOnSharedContext::BindImage(gl::GLImage* image,
bool client_managed) {
NOTIMPLEMENTED();
}
gl::GLImage* AbstractTextureImplOnSharedContext::GetImage() const {
NOTIMPLEMENTED();
return nullptr;
}
void AbstractTextureImplOnSharedContext::SetCleared() {
NOTIMPLEMENTED();
}
void AbstractTextureImplOnSharedContext::SetCleanupCallback(
CleanupCallback cb) {
cleanup_cb_ = std::move(cb);
}
void AbstractTextureImplOnSharedContext::OnContextLost() {
if (cleanup_cb_)
std::move(cleanup_cb_).Run(this);
shared_context_state_->RemoveContextLostObserver(this);
shared_context_state_ = nullptr;
}
} // namespace gles2
} // namespace gpu