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

Unified Diff: components/exo/buffer.cc

Issue 1412093006: components: Add Exosphere component. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove some ifdefs Created 5 years, 1 month 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
« no previous file with comments | « components/exo/buffer.h ('k') | components/exo/buffer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/exo/buffer.cc
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2f229ad65aa03a11715facc269442a50791ae877
--- /dev/null
+++ b/components/exo/buffer.cc
@@ -0,0 +1,187 @@
+// 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 "components/exo/buffer.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES2/gl2extchromium.h>
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "cc/output/context_provider.h"
+#include "cc/resources/single_release_callback.h"
+#include "cc/resources/texture_mailbox.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "ui/aura/env.h"
+#include "ui/compositor/compositor.h"
+#include "ui/gfx/gpu_memory_buffer.h"
+
+namespace exo {
+namespace {
+
+GLenum GLInternalFormat(gfx::BufferFormat format) {
+ const GLenum kGLInternalFormats[] = {
+ GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD, // ATC
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT, // ATCIA
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT, // DXT1
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, // DXT5
+ GL_ETC1_RGB8_OES, // ETC1
+ GL_R8_EXT, // R_8
+ GL_RGBA, // RGBA_4444
+ GL_RGB, // RGBX_8888
+ GL_RGBA, // RGBA_8888
+ GL_RGB, // BGRX_8888
+ GL_BGRA_EXT, // BGRA_8888
+ GL_RGB_YUV_420_CHROMIUM, // YUV_420
+ GL_INVALID_ENUM, // YUV_420_BIPLANAR
+ GL_RGB_YCBCR_422_CHROMIUM, // UYVY_422
+ };
+ static_assert(arraysize(kGLInternalFormats) ==
+ (static_cast<int>(gfx::BufferFormat::LAST) + 1),
+ "BufferFormat::LAST must be last value of kGLInternalFormats");
+
+ DCHECK(format <= gfx::BufferFormat::LAST);
+ return kGLInternalFormats[static_cast<int>(format)];
+}
+
+gpu::gles2::GLES2Interface* GetContextGL() {
+ ui::ContextFactory* context_factory =
+ aura::Env::GetInstance()->context_factory();
+ return context_factory->SharedMainThreadContextProvider()->ContextGL();
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// Buffer, public:
+
+Buffer::Buffer(scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer,
+ unsigned texture_target)
+ : gpu_memory_buffer_(gpu_memory_buffer.Pass()),
+ texture_target_(texture_target),
+ texture_id_(0),
+ image_id_(0) {
+ gpu::gles2::GLES2Interface* gles2 = GetContextGL();
+ // Create an image for |gpu_memory_buffer_|.
+ gfx::Size size = gpu_memory_buffer_->GetSize();
+ image_id_ = gles2->CreateImageCHROMIUM(
+ gpu_memory_buffer_->AsClientBuffer(), size.width(), size.height(),
+ GLInternalFormat(gpu_memory_buffer_->GetFormat()));
+ // Create a texture with |texture_target_|.
+ gles2->ActiveTexture(GL_TEXTURE0);
+ gles2->GenTextures(1, &texture_id_);
+ gles2->BindTexture(texture_target_, texture_id_);
+ gles2->TexParameteri(texture_target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gles2->TexParameteri(texture_target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gles2->TexParameteri(texture_target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gles2->TexParameteri(texture_target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ // Generate a crypto-secure random mailbox name.
+ gles2->GenMailboxCHROMIUM(mailbox_.name);
+ gles2->ProduceTextureCHROMIUM(texture_target_, mailbox_.name);
+}
+
+Buffer::~Buffer() {
+ gpu::gles2::GLES2Interface* gles2 = GetContextGL();
+ if (texture_id_)
+ gles2->DeleteTextures(1, &texture_id_);
+ if (image_id_)
+ gles2->DestroyImageCHROMIUM(image_id_);
+}
+
+scoped_ptr<cc::SingleReleaseCallback> Buffer::AcquireTextureMailbox(
+ cc::TextureMailbox* texture_mailbox) {
+ // Buffer can only be used by one client at a time. If texture id is 0, then a
+ // previous call to AcquireTextureMailbox() is using this buffer and it has
+ // not been released yet.
+ if (!texture_id_) {
+ DLOG(WARNING) << "Client tried to use a buffer that has not been released";
+ return nullptr;
+ }
+
+ // Take ownerhsip of image and texture ids.
+ unsigned texture_id = 0;
+ unsigned image_id = 0;
+ std::swap(texture_id, texture_id_);
+ DCHECK_NE(image_id_, 0u);
+ std::swap(image_id, image_id_);
+
+ // Bind texture to |texture_target_|.
+ gpu::gles2::GLES2Interface* gles2 = GetContextGL();
+ gles2->ActiveTexture(GL_TEXTURE0);
+ gles2->BindTexture(texture_target_, texture_id);
+
+ // Bind the image to texture.
+ gles2->BindTexImage2DCHROMIUM(texture_target_, image_id);
+
+ // Create a sync token to ensure that the BindTexImage2DCHROMIUM call is
+ // processed before issuing any commands that will read from texture.
+ uint64 fence_sync = gles2->InsertFenceSyncCHROMIUM();
+ gles2->ShallowFlushCHROMIUM();
+ gpu::SyncToken sync_token;
+ gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
+
+ bool is_overlay_candidate = false;
+ *texture_mailbox =
+ cc::TextureMailbox(mailbox_, sync_token, texture_target_,
+ gpu_memory_buffer_->GetSize(), is_overlay_candidate);
+ return cc::SingleReleaseCallback::Create(
+ base::Bind(&Buffer::Release, AsWeakPtr(), texture_target_,
+ texture_id, image_id))
+ .Pass();
+}
+
+gfx::Size Buffer::GetSize() const {
+ return gpu_memory_buffer_->GetSize();
+}
+
+scoped_refptr<base::trace_event::TracedValue> Buffer::AsTracedValue() const {
+ scoped_refptr<base::trace_event::TracedValue> value =
+ new base::trace_event::TracedValue;
+ value->SetInteger("width", GetSize().width());
+ value->SetInteger("height", GetSize().height());
+ value->SetInteger("format",
+ static_cast<int>(gpu_memory_buffer_->GetFormat()));
+ return value;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Buffer, private:
+
+// static
+void Buffer::Release(base::WeakPtr<Buffer> buffer,
+ unsigned texture_target,
+ unsigned texture_id,
+ unsigned image_id,
+ const gpu::SyncToken& sync_token,
+ bool is_lost) {
+ TRACE_EVENT1("exo", "Buffer::Release", "is_lost", is_lost);
+
+ gpu::gles2::GLES2Interface* gles2 = GetContextGL();
+ if (sync_token.HasData())
+ gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
+ gles2->ActiveTexture(GL_TEXTURE0);
+ gles2->BindTexture(texture_target, texture_id);
+ gles2->ReleaseTexImage2DCHROMIUM(texture_target, image_id);
+
+ // Delete resources and return if buffer is gone.
+ if (!buffer) {
+ gles2->DeleteTextures(1, &texture_id);
+ gles2->DestroyImageCHROMIUM(image_id);
+ return;
+ }
+
+ DCHECK_EQ(buffer->texture_id_, 0u);
+ buffer->texture_id_ = texture_id;
+ DCHECK_EQ(buffer->image_id_, 0u);
+ buffer->image_id_ = image_id;
+
+ if (!buffer->release_callback_.is_null())
+ buffer->release_callback_.Run();
+}
+
+} // namespace exo
« no previous file with comments | « components/exo/buffer.h ('k') | components/exo/buffer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698