| Index: content/renderer/gpu/mailbox_output_surface.cc
|
| diff --git a/content/renderer/gpu/mailbox_output_surface.cc b/content/renderer/gpu/mailbox_output_surface.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4e0a8634dd544b6b4373b85a34c6e9d557731613
|
| --- /dev/null
|
| +++ b/content/renderer/gpu/mailbox_output_surface.cc
|
| @@ -0,0 +1,164 @@
|
| +// Copyright (c) 2012 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 "content/renderer/gpu/mailbox_output_surface.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "cc/compositor_frame.h"
|
| +#include "cc/compositor_frame_ack.h"
|
| +#include "cc/gl_frame_data.h"
|
| +#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
|
| +#include "third_party/khronos/GLES2/gl2.h"
|
| +#include "third_party/khronos/GLES2/gl2ext.h"
|
| +
|
| +using cc::CompositorFrame;
|
| +using cc::GLFrameData;
|
| +using cc::Mailbox;
|
| +using WebKit::WebGraphicsContext3D;
|
| +
|
| +namespace content {
|
| +
|
| +MailboxOutputSurface::MailboxOutputSurface(
|
| + int32 routing_id,
|
| + WebGraphicsContext3D* context3D,
|
| + cc::SoftwareOutputDevice* software_device)
|
| + : CompositorOutputSurface(routing_id,
|
| + context3D,
|
| + software_device),
|
| + fbo_(0) {
|
| +}
|
| +
|
| +MailboxOutputSurface::~MailboxOutputSurface() {
|
| + DiscardBackbuffer();
|
| +}
|
| +
|
| +void MailboxOutputSurface::EnsureBackbuffer() {
|
| + if (!current_backing_.texture_id) {
|
| + // Find a texture of matching size to recycle.
|
| + while (!returned_textures_.empty()) {
|
| + TransferableFrame& texture = returned_textures_.front();
|
| + if (texture.size == size_) {
|
| + current_backing_ = texture;
|
| + returned_textures_.pop();
|
| + break;
|
| + }
|
| +
|
| + context3d_->deleteTexture(texture.texture_id);
|
| + returned_textures_.pop();
|
| + }
|
| +
|
| + if (!current_backing_.texture_id) {
|
| + current_backing_.texture_id = context3d_->createTexture();
|
| + current_backing_.size = size_;
|
| + context3d_->genMailboxCHROMIUM(current_backing_.mailbox.name);
|
| + context3d_->bindTexture(GL_TEXTURE_2D, current_backing_.texture_id);
|
| + context3d_->texParameteri(
|
| + GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| + context3d_->texParameteri(
|
| + GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
| + context3d_->texParameteri(
|
| + GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| + context3d_->texParameteri(
|
| + GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| + context3d_->texImage2D(
|
| + GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), 0,
|
| + GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void MailboxOutputSurface::DiscardBackbuffer() {
|
| + if (current_backing_.texture_id) {
|
| + context3d_->deleteTexture(current_backing_.texture_id);
|
| + current_backing_ = TransferableFrame();
|
| + }
|
| +
|
| + while (!returned_textures_.empty()) {
|
| + context3d_->deleteTexture(returned_textures_.front().texture_id);
|
| + returned_textures_.pop();
|
| + }
|
| +
|
| + if (fbo_) {
|
| + context3d_->bindFramebuffer(GL_FRAMEBUFFER, fbo_);
|
| + context3d_->deleteFramebuffer(fbo_);
|
| + fbo_ = 0;
|
| + }
|
| +}
|
| +
|
| +void MailboxOutputSurface::Reshape(gfx::Size size) {
|
| + if (size == size_)
|
| + return;
|
| +
|
| + size_ = size;
|
| + DiscardBackbuffer();
|
| + EnsureBackbuffer();
|
| +}
|
| +
|
| +void MailboxOutputSurface::BindFramebuffer() {
|
| + EnsureBackbuffer();
|
| + DCHECK(current_backing_.texture_id);
|
| +
|
| + if (!fbo_)
|
| + fbo_ = context3d_->createFramebuffer();
|
| + context3d_->bindFramebuffer(GL_FRAMEBUFFER, fbo_);
|
| + context3d_->framebufferTexture2D(
|
| + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
| + current_backing_.texture_id, 0);
|
| +}
|
| +
|
| +void MailboxOutputSurface::SendFrameToParentCompositor(
|
| + cc::CompositorFrame* frame) {
|
| + frame->gl_frame_data.reset(new GLFrameData());
|
| +
|
| + DCHECK(!size_.IsEmpty());
|
| + DCHECK(size_ == current_backing_.size);
|
| + DCHECK(!current_backing_.mailbox.isZero());
|
| +
|
| + context3d_->framebufferTexture2D(
|
| + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
| + context3d_->bindTexture(GL_TEXTURE_2D, current_backing_.texture_id);
|
| + context3d_->produceTextureCHROMIUM(
|
| + GL_TEXTURE_2D, current_backing_.mailbox.name);
|
| + frame->gl_frame_data->mailbox = current_backing_.mailbox;
|
| + frame->gl_frame_data->size = current_backing_.size;
|
| + context3d_->flush();
|
| + frame->gl_frame_data->sync_point = context3d_->insertSyncPoint();
|
| + CompositorOutputSurface::SendFrameToParentCompositor(frame);
|
| +
|
| + // TODO(sievers): Reuse the texture.
|
| + context3d_->deleteTexture(current_backing_.texture_id);
|
| + current_backing_ = TransferableFrame();
|
| +}
|
| +
|
| +void MailboxOutputSurface::OnSwapAck(const cc::CompositorFrameAck& ack) {
|
| + if (!ack.gl_frame_data->mailbox.isZero()) {
|
| + DCHECK(!ack.gl_frame_data->size.IsEmpty());
|
| + uint32 texture_id = context3d_->createTexture();
|
| + TransferableFrame texture(
|
| + texture_id, ack.gl_frame_data->mailbox, ack.gl_frame_data->size);
|
| +
|
| + context3d_->bindTexture(GL_TEXTURE_2D, texture_id);
|
| +
|
| + // If the consumer is bouncing back the same texture (i.e. skipping the
|
| + // frame), we don't have to synchronize here (sync_point == 0).
|
| + // TODO: Consider delaying the wait and consume until BindFramebuffer.
|
| + if (ack.gl_frame_data->sync_point)
|
| + context3d_->waitSyncPoint(ack.gl_frame_data->sync_point);
|
| +
|
| + context3d_->consumeTextureCHROMIUM(
|
| + GL_TEXTURE_2D, ack.gl_frame_data->mailbox.name);
|
| + returned_textures_.push(texture);
|
| + }
|
| + CompositorOutputSurface::OnSwapAck(ack);
|
| +}
|
| +
|
| +void MailboxOutputSurface::SwapBuffers() {
|
| +}
|
| +
|
| +void MailboxOutputSurface::PostSubBuffer(gfx::Rect rect) {
|
| + NOTIMPLEMENTED()
|
| + << "Partial swap not supported with composite-to-mailbox yet.";
|
| +}
|
| +
|
| +} // namespace content
|
|
|