Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Unified Diff: mojo/ui/gl_renderer.cc

Issue 1556803002: Add helpers for creating UI components. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-13
Patch Set: Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/ui/gl_renderer.cc
diff --git a/mojo/ui/gl_renderer.cc b/mojo/ui/gl_renderer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3adf50782b78f6f03ce575fe9ca7ca7bfe71176d
--- /dev/null
+++ b/mojo/ui/gl_renderer.cc
@@ -0,0 +1,161 @@
+// Copyright 2015 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 "mojo/ui/gl_renderer.h"
+
+#ifndef GL_GLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+#endif
+#include <GLES2/gl2.h>
+#include <GLES2/gl2extmojo.h>
+
+#include "mojo/gpu/gl_context.h"
+#include "mojo/gpu/gl_texture.h"
+
+namespace mojo {
+namespace ui {
+
+GLRenderer::GLRenderer(base::WeakPtr<mojo::GLContext> gl_context,
+ uint32_t max_recycled_textures)
+ : gl_context_(gl_context),
+ max_recycled_textures_(max_recycled_textures),
+ weak_factory_(this) {}
+
+GLRenderer::~GLRenderer() {}
+
+std::unique_ptr<mojo::GLTexture> GLRenderer::GetTexture(
+ const mojo::Size& requested_size) {
+ if (!gl_context_) {
+ recycled_textures_.clear();
+ return nullptr;
+ }
+
+ while (!recycled_textures_.empty()) {
+ GLRecycledTextureInfo texture_info(std::move(recycled_textures_.front()));
+ recycled_textures_.pop_front();
+ if (texture_info.first->size().Equals(requested_size)) {
+ gl_context_->MakeCurrent();
+ glWaitSyncPointCHROMIUM(texture_info.second);
+ return std::move(texture_info.first);
+ }
+ }
+
+ return std::unique_ptr<GLTexture>(new GLTexture(gl_context_, requested_size));
+}
+
+mojo::gfx::composition::ResourcePtr GLRenderer::BindTextureResource(
+ std::unique_ptr<GLTexture> texture) {
+ if (!gl_context_)
+ return nullptr;
+
+ // Produce the texture.
+ gl_context_->MakeCurrent();
+ glBindTexture(GL_TEXTURE_2D, texture->texture_id());
+ GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
+ glGenMailboxCHROMIUM(mailbox);
+ glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ GLuint sync_point = glInsertSyncPointCHROMIUM();
+
+ // Populate the resource description.
+ auto resource = mojo::gfx::composition::Resource::New();
+ resource->set_mailbox_texture(
+ mojo::gfx::composition::MailboxTextureResource::New());
+ resource->get_mailbox_texture()->mailbox_name.resize(sizeof(mailbox));
+ memcpy(resource->get_mailbox_texture()->mailbox_name.data(), mailbox,
+ sizeof(mailbox));
+ resource->get_mailbox_texture()->sync_point = sync_point;
+ resource->get_mailbox_texture()->size = texture->size().Clone();
+ resource->get_mailbox_texture()->callback =
+ (new GLTextureReleaser(
+ weak_factory_.GetWeakPtr(),
+ GLRecycledTextureInfo(std::move(texture), sync_point)))
+ ->StrongBind()
+ .Pass();
+
+ bound_textures_++;
+ DVLOG(2) << "bind: bound_textures=" << bound_textures_;
+ return resource;
+}
+
+mojo::gfx::composition::ResourcePtr GLRenderer::DrawGL(
+ const mojo::Size& size,
+ bool with_depth,
+ const DrawGLCallback& callback) {
+ std::unique_ptr<mojo::GLTexture> texture = GetTexture(size);
+ DCHECK(texture);
+
+ GLuint fbo = 0u;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ texture->texture_id(), 0);
+
+ GLuint depth_buffer = 0u;
+ if (with_depth) {
+ glGenRenderbuffers(1, &depth_buffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.width,
+ size.height);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_buffer);
+ }
+
+ DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ glViewport(0, 0, size.width, size.height);
+ callback.Run();
+
+ if (with_depth)
+ glDeleteRenderbuffers(1, &depth_buffer);
+ glDeleteFramebuffers(1, &fbo);
+
+ return BindTextureResource(std::move(texture));
+}
+
+void GLRenderer::ReleaseTexture(GLRecycledTextureInfo texture_info,
+ bool recyclable) {
+ DCHECK(bound_textures_);
+ bound_textures_--;
+ if (recyclable && recycled_textures_.size() < max_recycled_textures_) {
+ recycled_textures_.emplace_back(std::move(texture_info));
+ }
+ DVLOG(2) << "release: bound_textures=" << bound_textures_
+ << ", recycled_textures=" << recycled_textures_.size();
+}
+
+GLRenderer::GLTextureReleaser::GLTextureReleaser(
+ const base::WeakPtr<GLRenderer>& provider,
+ GLRecycledTextureInfo info)
+ : provider_(provider), texture_info_(std::move(info)), binding_(this) {}
+
+GLRenderer::GLTextureReleaser::~GLTextureReleaser() {
+ // It's possible for the object to be destroyed due to a connection
+ // error on the callback pipe. When this happens we don't want to
+ // recycle the texture since we have too little knowledge about its
+ // state to confirm that it will be safe to do so.
+ Release(false /*recyclable*/);
+}
+
+mojo::gfx::composition::MailboxTextureCallbackPtr
+GLRenderer::GLTextureReleaser::StrongBind() {
+ mojo::gfx::composition::MailboxTextureCallbackPtr callback;
+ binding_.Bind(mojo::GetProxy(&callback));
+ return callback;
+}
+
+void GLRenderer::GLTextureReleaser::OnMailboxTextureReleased() {
+ Release(true /*recyclable*/);
+}
+
+void GLRenderer::GLTextureReleaser::Release(bool recyclable) {
+ if (provider_) {
+ provider_->ReleaseTexture(std::move(texture_info_), recyclable);
+ provider_.reset();
+ }
+}
+
+} // namespace ui
+} // namespace mojo

Powered by Google App Engine
This is Rietveld 408576698