| Index: content/common/gpu/texture_image_transport_surface.cc
|
| diff --git a/content/common/gpu/texture_image_transport_surface.cc b/content/common/gpu/texture_image_transport_surface.cc
|
| deleted file mode 100644
|
| index f51f54515229f02049d329b395452736c421ca4c..0000000000000000000000000000000000000000
|
| --- a/content/common/gpu/texture_image_transport_surface.cc
|
| +++ /dev/null
|
| @@ -1,460 +0,0 @@
|
| -// 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/common/gpu/texture_image_transport_surface.h"
|
| -
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/command_line.h"
|
| -#include "content/common/gpu/gpu_channel.h"
|
| -#include "content/common/gpu/gpu_channel_manager.h"
|
| -#include "content/common/gpu/gpu_messages.h"
|
| -#include "content/common/gpu/sync_point_manager.h"
|
| -#include "content/public/common/content_switches.h"
|
| -#include "gpu/command_buffer/service/context_group.h"
|
| -#include "gpu/command_buffer/service/gpu_scheduler.h"
|
| -#include "gpu/command_buffer/service/mailbox_manager.h"
|
| -#include "ui/gl/scoped_binders.h"
|
| -
|
| -using gpu::gles2::ContextGroup;
|
| -using gpu::gles2::GLES2Decoder;
|
| -using gpu::gles2::MailboxManager;
|
| -using gpu::gles2::Texture;
|
| -using gpu::gles2::TextureManager;
|
| -using gpu::gles2::TextureRef;
|
| -using gpu::Mailbox;
|
| -
|
| -namespace content {
|
| -namespace {
|
| -
|
| -bool IsContextValid(ImageTransportHelper* helper) {
|
| - return helper->stub()->decoder()->GetGLContext()->IsCurrent(NULL);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -TextureImageTransportSurface::TextureImageTransportSurface(
|
| - GpuChannelManager* manager,
|
| - GpuCommandBufferStub* stub,
|
| - const gfx::GLSurfaceHandle& handle)
|
| - : fbo_id_(0),
|
| - current_size_(1, 1),
|
| - scale_factor_(1.f),
|
| - stub_destroyed_(false),
|
| - backbuffer_suggested_allocation_(true),
|
| - frontbuffer_suggested_allocation_(true),
|
| - handle_(handle),
|
| - is_swap_buffers_pending_(false),
|
| - did_unschedule_(false) {
|
| - helper_.reset(new ImageTransportHelper(this,
|
| - manager,
|
| - stub,
|
| - gfx::kNullPluginWindow));
|
| -}
|
| -
|
| -TextureImageTransportSurface::~TextureImageTransportSurface() {
|
| - DCHECK(stub_destroyed_);
|
| - Destroy();
|
| -}
|
| -
|
| -bool TextureImageTransportSurface::Initialize() {
|
| - mailbox_manager_ =
|
| - helper_->stub()->decoder()->GetContextGroup()->mailbox_manager();
|
| -
|
| - GpuChannelManager* manager = helper_->manager();
|
| - surface_ = manager->GetDefaultOffscreenSurface();
|
| - if (!surface_.get())
|
| - return false;
|
| -
|
| - if (!helper_->Initialize())
|
| - return false;
|
| -
|
| - GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id);
|
| - if (parent_channel) {
|
| - const base::CommandLine* command_line =
|
| - base::CommandLine::ForCurrentProcess();
|
| - if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
|
| - helper_->SetPreemptByFlag(parent_channel->GetPreemptionFlag());
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void TextureImageTransportSurface::Destroy() {
|
| - if (surface_.get())
|
| - surface_ = NULL;
|
| -
|
| - helper_->Destroy();
|
| -}
|
| -
|
| -bool TextureImageTransportSurface::DeferDraws() {
|
| - // The command buffer hit a draw/clear command that could clobber the
|
| - // texture in use by the UI compositor. If a Swap is pending, abort
|
| - // processing of the command by returning true and unschedule until the Swap
|
| - // Ack arrives.
|
| - DCHECK(!did_unschedule_);
|
| - if (is_swap_buffers_pending_) {
|
| - did_unschedule_ = true;
|
| - helper_->SetScheduled(false);
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool TextureImageTransportSurface::IsOffscreen() {
|
| - return true;
|
| -}
|
| -
|
| -unsigned int TextureImageTransportSurface::GetBackingFrameBufferObject() {
|
| - DCHECK(IsContextValid(helper_.get()));
|
| - if (!fbo_id_) {
|
| - glGenFramebuffersEXT(1, &fbo_id_);
|
| - glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_);
|
| - helper_->stub()->AddDestructionObserver(this);
|
| - CreateBackTexture();
|
| - }
|
| -
|
| - return fbo_id_;
|
| -}
|
| -
|
| -bool TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) {
|
| - DCHECK(!is_swap_buffers_pending_);
|
| - if (backbuffer_suggested_allocation_ == allocation)
|
| - return true;
|
| - backbuffer_suggested_allocation_ = allocation;
|
| -
|
| - if (backbuffer_suggested_allocation_) {
|
| - DCHECK(!backbuffer_.get());
|
| - CreateBackTexture();
|
| - } else {
|
| - ReleaseBackTexture();
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) {
|
| - if (frontbuffer_suggested_allocation_ == allocation)
|
| - return;
|
| - frontbuffer_suggested_allocation_ = allocation;
|
| -
|
| - // If a swapbuffers is in flight, wait for the ack before releasing the front
|
| - // buffer:
|
| - // - we don't know yet which texture the browser will want to keep
|
| - // - we want to ensure we don't destroy a texture that is in flight before the
|
| - // browser got a reference on it.
|
| - if (!frontbuffer_suggested_allocation_ &&
|
| - !is_swap_buffers_pending_ &&
|
| - helper_->MakeCurrent()) {
|
| - ReleaseFrontTexture();
|
| - }
|
| -}
|
| -
|
| -void* TextureImageTransportSurface::GetShareHandle() {
|
| - return GetHandle();
|
| -}
|
| -
|
| -void* TextureImageTransportSurface::GetDisplay() {
|
| - return surface_.get() ? surface_->GetDisplay() : NULL;
|
| -}
|
| -
|
| -void* TextureImageTransportSurface::GetConfig() {
|
| - return surface_.get() ? surface_->GetConfig() : NULL;
|
| -}
|
| -
|
| -void TextureImageTransportSurface::OnResize(gfx::Size size,
|
| - float scale_factor) {
|
| - DCHECK_GE(size.width(), 1);
|
| - DCHECK_GE(size.height(), 1);
|
| - current_size_ = size;
|
| - scale_factor_ = scale_factor;
|
| - if (backbuffer_suggested_allocation_)
|
| - CreateBackTexture();
|
| -}
|
| -
|
| -void TextureImageTransportSurface::OnWillDestroyStub() {
|
| - bool have_context = IsContextValid(helper_.get());
|
| - helper_->stub()->RemoveDestructionObserver(this);
|
| -
|
| - // We are losing the stub owning us, this is our last chance to clean up the
|
| - // resources we allocated in the stub's context.
|
| - if (have_context) {
|
| - ReleaseBackTexture();
|
| - ReleaseFrontTexture();
|
| - } else {
|
| - backbuffer_ = NULL;
|
| - back_mailbox_ = Mailbox();
|
| - frontbuffer_ = NULL;
|
| - front_mailbox_ = Mailbox();
|
| - }
|
| -
|
| - if (fbo_id_ && have_context) {
|
| - glDeleteFramebuffersEXT(1, &fbo_id_);
|
| - CHECK_GL_ERROR();
|
| - }
|
| - fbo_id_ = 0;
|
| -
|
| - stub_destroyed_ = true;
|
| -}
|
| -
|
| -void TextureImageTransportSurface::SetLatencyInfo(
|
| - const std::vector<ui::LatencyInfo>& latency_info) {
|
| - for (size_t i = 0; i < latency_info.size(); i++)
|
| - latency_info_.push_back(latency_info[i]);
|
| -}
|
| -
|
| -void TextureImageTransportSurface::WakeUpGpu() {
|
| - NOTIMPLEMENTED();
|
| -}
|
| -
|
| -bool TextureImageTransportSurface::SwapBuffers() {
|
| - DCHECK(IsContextValid(helper_.get()));
|
| - DCHECK(backbuffer_suggested_allocation_);
|
| -
|
| - if (!frontbuffer_suggested_allocation_)
|
| - return true;
|
| -
|
| - if (!backbuffer_.get()) {
|
| - LOG(ERROR) << "Swap without valid backing.";
|
| - return true;
|
| - }
|
| -
|
| - DCHECK(backbuffer_size() == current_size_);
|
| - GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
|
| - params.size = backbuffer_size();
|
| - params.scale_factor = scale_factor_;
|
| - params.mailbox = back_mailbox_;
|
| -
|
| - glFlush();
|
| -
|
| - params.latency_info.swap(latency_info_);
|
| - helper_->SendAcceleratedSurfaceBuffersSwapped(params);
|
| -
|
| - DCHECK(!is_swap_buffers_pending_);
|
| - is_swap_buffers_pending_ = true;
|
| - return true;
|
| -}
|
| -
|
| -bool TextureImageTransportSurface::PostSubBuffer(
|
| - int x, int y, int width, int height) {
|
| - DCHECK(IsContextValid(helper_.get()));
|
| - DCHECK(backbuffer_suggested_allocation_);
|
| - if (!frontbuffer_suggested_allocation_)
|
| - return true;
|
| - const gfx::Rect new_damage_rect(x, y, width, height);
|
| - DCHECK(gfx::Rect(gfx::Point(), current_size_).Contains(new_damage_rect));
|
| -
|
| - // An empty damage rect is a successful no-op.
|
| - if (new_damage_rect.IsEmpty())
|
| - return true;
|
| -
|
| - if (!backbuffer_.get()) {
|
| - LOG(ERROR) << "Swap without valid backing.";
|
| - return true;
|
| - }
|
| -
|
| - DCHECK(current_size_ == backbuffer_size());
|
| - GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
|
| - params.surface_size = backbuffer_size();
|
| - params.surface_scale_factor = scale_factor_;
|
| - params.x = x;
|
| - params.y = y;
|
| - params.width = width;
|
| - params.height = height;
|
| - params.mailbox = back_mailbox_;
|
| -
|
| - glFlush();
|
| -
|
| - params.latency_info.swap(latency_info_);
|
| - helper_->SendAcceleratedSurfacePostSubBuffer(params);
|
| -
|
| - DCHECK(!is_swap_buffers_pending_);
|
| - is_swap_buffers_pending_ = true;
|
| - return true;
|
| -}
|
| -
|
| -bool TextureImageTransportSurface::SupportsPostSubBuffer() {
|
| - return true;
|
| -}
|
| -
|
| -gfx::Size TextureImageTransportSurface::GetSize() {
|
| - return current_size_;
|
| -}
|
| -
|
| -void* TextureImageTransportSurface::GetHandle() {
|
| - return surface_.get() ? surface_->GetHandle() : NULL;
|
| -}
|
| -
|
| -unsigned TextureImageTransportSurface::GetFormat() {
|
| - return surface_.get() ? surface_->GetFormat() : 0;
|
| -}
|
| -
|
| -void TextureImageTransportSurface::OnBufferPresented(
|
| - const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
|
| - if (params.sync_point == 0) {
|
| - BufferPresentedImpl(params.mailbox);
|
| - } else {
|
| - helper_->manager()->sync_point_manager()->AddSyncPointCallback(
|
| - params.sync_point,
|
| - base::Bind(&TextureImageTransportSurface::BufferPresentedImpl,
|
| - this,
|
| - params.mailbox));
|
| - }
|
| -}
|
| -
|
| -void TextureImageTransportSurface::BufferPresentedImpl(const Mailbox& mailbox) {
|
| - DCHECK(is_swap_buffers_pending_);
|
| - is_swap_buffers_pending_ = false;
|
| -
|
| - // When we wait for a sync point, we may get called back after the stub is
|
| - // destroyed. In that case there's no need to do anything with the returned
|
| - // mailbox.
|
| - if (stub_destroyed_)
|
| - return;
|
| -
|
| - // We should not have allowed the backbuffer to be discarded while the ack
|
| - // was pending.
|
| - DCHECK(backbuffer_suggested_allocation_);
|
| - DCHECK(backbuffer_.get());
|
| -
|
| - bool swap = true;
|
| - if (!mailbox.IsZero()) {
|
| - if (mailbox == back_mailbox_) {
|
| - // The browser has skipped the frame to unblock the GPU process, waiting
|
| - // for one of the right size, and returned the back buffer, so don't swap.
|
| - swap = false;
|
| - }
|
| - }
|
| - if (swap) {
|
| - std::swap(backbuffer_, frontbuffer_);
|
| - std::swap(back_mailbox_, front_mailbox_);
|
| - }
|
| -
|
| - // We're relying on the fact that the parent context is
|
| - // finished with its context when it inserts the sync point that
|
| - // triggers this callback.
|
| - if (helper_->MakeCurrent()) {
|
| - if (frontbuffer_.get() && !frontbuffer_suggested_allocation_)
|
| - ReleaseFrontTexture();
|
| - if (!backbuffer_.get() || backbuffer_size() != current_size_)
|
| - CreateBackTexture();
|
| - else
|
| - AttachBackTextureToFBO();
|
| - }
|
| -
|
| - // Even if MakeCurrent fails, schedule anyway, to trigger the lost context
|
| - // logic.
|
| - if (did_unschedule_) {
|
| - did_unschedule_ = false;
|
| - helper_->SetScheduled(true);
|
| - }
|
| -}
|
| -
|
| -void TextureImageTransportSurface::ReleaseBackTexture() {
|
| - DCHECK(IsContextValid(helper_.get()));
|
| - backbuffer_ = NULL;
|
| - back_mailbox_ = Mailbox();
|
| - glFlush();
|
| - CHECK_GL_ERROR();
|
| -}
|
| -
|
| -void TextureImageTransportSurface::ReleaseFrontTexture() {
|
| - DCHECK(IsContextValid(helper_.get()));
|
| - frontbuffer_ = NULL;
|
| - front_mailbox_ = Mailbox();
|
| - glFlush();
|
| - CHECK_GL_ERROR();
|
| - helper_->SendAcceleratedSurfaceRelease();
|
| -}
|
| -
|
| -void TextureImageTransportSurface::CreateBackTexture() {
|
| - DCHECK(IsContextValid(helper_.get()));
|
| - // If |is_swap_buffers_pending| we are waiting for our backbuffer
|
| - // in the mailbox, so we shouldn't be reallocating it now.
|
| - DCHECK(!is_swap_buffers_pending_);
|
| -
|
| - if (backbuffer_.get() && backbuffer_size() == current_size_)
|
| - return;
|
| -
|
| - VLOG(1) << "Allocating new backbuffer texture";
|
| -
|
| - GLES2Decoder* decoder = helper_->stub()->decoder();
|
| - TextureManager* texture_manager =
|
| - decoder->GetContextGroup()->texture_manager();
|
| - if (!backbuffer_.get()) {
|
| - back_mailbox_ = gpu::Mailbox::Generate();
|
| - GLuint service_id;
|
| - glGenTextures(1, &service_id);
|
| - backbuffer_ = TextureRef::Create(texture_manager, 0, service_id);
|
| - texture_manager->SetTarget(backbuffer_.get(), GL_TEXTURE_2D);
|
| - Texture* texture = texture_manager->Produce(backbuffer_.get());
|
| - mailbox_manager_->ProduceTexture(GL_TEXTURE_2D, back_mailbox_, texture);
|
| - }
|
| -
|
| - {
|
| - gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D,
|
| - backbuffer_->service_id());
|
| - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
| - current_size_.width(), current_size_.height(), 0,
|
| - GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
| - gpu::gles2::ErrorState* error_state = decoder->GetErrorState();
|
| - texture_manager->SetParameteri("Backbuffer",
|
| - error_state,
|
| - backbuffer_.get(),
|
| - GL_TEXTURE_MIN_FILTER,
|
| - GL_LINEAR);
|
| - texture_manager->SetParameteri("Backbuffer",
|
| - error_state,
|
| - backbuffer_.get(),
|
| - GL_TEXTURE_MAG_FILTER,
|
| - GL_LINEAR);
|
| - texture_manager->SetParameteri("Backbuffer",
|
| - error_state,
|
| - backbuffer_.get(),
|
| - GL_TEXTURE_WRAP_S,
|
| - GL_CLAMP_TO_EDGE);
|
| - texture_manager->SetParameteri("Backbuffer",
|
| - error_state,
|
| - backbuffer_.get(),
|
| - GL_TEXTURE_WRAP_T,
|
| - GL_CLAMP_TO_EDGE);
|
| - texture_manager->SetLevelInfo(backbuffer_.get(),
|
| - GL_TEXTURE_2D,
|
| - 0,
|
| - GL_RGBA,
|
| - current_size_.width(),
|
| - current_size_.height(),
|
| - 1,
|
| - 0,
|
| - GL_RGBA,
|
| - GL_UNSIGNED_BYTE,
|
| - true);
|
| - DCHECK(texture_manager->CanRender(backbuffer_.get()));
|
| - CHECK_GL_ERROR();
|
| - }
|
| -
|
| - AttachBackTextureToFBO();
|
| -}
|
| -
|
| -void TextureImageTransportSurface::AttachBackTextureToFBO() {
|
| - DCHECK(IsContextValid(helper_.get()));
|
| - DCHECK(backbuffer_.get());
|
| - gfx::ScopedFrameBufferBinder fbo_binder(fbo_id_);
|
| - glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
|
| - GL_COLOR_ATTACHMENT0,
|
| - GL_TEXTURE_2D,
|
| - backbuffer_->service_id(),
|
| - 0);
|
| - CHECK_GL_ERROR();
|
| -
|
| -#ifndef NDEBUG
|
| - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
|
| - if (status != GL_FRAMEBUFFER_COMPLETE) {
|
| - DLOG(FATAL) << "Framebuffer incomplete: " << status;
|
| - }
|
| -#endif
|
| -}
|
| -
|
| -} // namespace content
|
|
|