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 |