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

Unified Diff: content/common/gpu/image_transport_surface_fbo_mac.mm

Issue 1416363002: Mac: Always use surfaceless mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add export Created 5 years, 2 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: content/common/gpu/image_transport_surface_fbo_mac.mm
diff --git a/content/common/gpu/image_transport_surface_fbo_mac.mm b/content/common/gpu/image_transport_surface_fbo_mac.mm
deleted file mode 100644
index 3b6aa0fb8332b08d6838c83d64df0a5c6b6a8738..0000000000000000000000000000000000000000
--- a/content/common/gpu/image_transport_surface_fbo_mac.mm
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright 2014 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/image_transport_surface_fbo_mac.h"
-
-#include "base/command_line.h"
-#include "base/trace_event/trace_event.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/common/gpu/image_transport_surface_calayer_mac.h"
-#include "content/common/gpu/image_transport_surface_iosurface_mac.h"
-#include "content/common/gpu/image_transport_surface_overlay_mac.h"
-#include "ui/base/cocoa/remote_layer_api.h"
-#include "ui/base/ui_base_switches.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_surface_osmesa.h"
-
-namespace content {
-
-scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::PluginWindowHandle handle) {
- // Overlays should be used unless the remote layer API isn't present (they
- // depend on it) or it is disabled at the command line.
- static bool overlays_disabled_at_command_line =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableMacOverlays);
- if (ui::RemoteLayerAPISupported() && !overlays_disabled_at_command_line)
- return new ImageTransportSurfaceOverlayMac(manager, stub, handle);
- else
- return new ImageTransportSurfaceFBO(manager, stub, handle);
-}
-
-ImageTransportSurfaceFBO::ImageTransportSurfaceFBO(
- GpuChannelManager* manager,
- GpuCommandBufferStub* stub,
- gfx::PluginWindowHandle handle)
- : backbuffer_suggested_allocation_(true),
- frontbuffer_suggested_allocation_(true),
- fbo_id_(0),
- texture_id_(0),
- depth_stencil_renderbuffer_id_(0),
- has_complete_framebuffer_(false),
- context_(NULL),
- scale_factor_(1.f),
- made_current_(false),
- is_swap_buffers_send_pending_(false) {
- if (ui::RemoteLayerAPISupported())
- storage_provider_.reset(new CALayerStorageProvider(this));
- else
- storage_provider_.reset(new IOSurfaceStorageProvider(this));
- helper_.reset(new ImageTransportHelper(this, manager, stub, handle));
-}
-
-ImageTransportSurfaceFBO::~ImageTransportSurfaceFBO() {
-}
-
-bool ImageTransportSurfaceFBO::Initialize() {
- // Only support IOSurfaces if the GL implementation is the native desktop GL.
- // IO surfaces will not work with, for example, OSMesa software renderer
- // GL contexts.
- if (gfx::GetGLImplementation() !=
- gfx::kGLImplementationDesktopGLCoreProfile &&
- gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL &&
- gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL)
- return false;
-
- if (!helper_->Initialize())
- return false;
-
- helper_->stub()->AddDestructionObserver(this);
- return true;
-}
-
-void ImageTransportSurfaceFBO::Destroy() {
- DestroyFramebuffer();
-}
-
-bool ImageTransportSurfaceFBO::DeferDraws() {
- storage_provider_->WillWriteToBackbuffer();
- // We should not have a pending send when we are drawing the next frame.
- DCHECK(!is_swap_buffers_send_pending_);
-
- // The call to WillWriteToBackbuffer could potentially force a draw. Ensure
- // that any changes made to the context's state are restored.
- context_->RestoreStateIfDirtiedExternally();
- return false;
-}
-
-bool ImageTransportSurfaceFBO::IsOffscreen() {
- return false;
-}
-
-bool ImageTransportSurfaceFBO::OnMakeCurrent(gfx::GLContext* context) {
- context_ = context;
-
- if (made_current_)
- return true;
-
- AllocateOrResizeFramebuffer(gfx::Size(1, 1), 1.f);
-
- made_current_ = true;
- return true;
-}
-
-void ImageTransportSurfaceFBO::NotifyWasBound() {
- // Sometimes calling glBindFramebuffer doesn't seem to be enough to get
- // rendered contents to show up in the color attachment. It appears that doing
- // a glBegin/End pair with program 0 is enough to tickle the driver into
- // actually effecting the binding.
- // http://crbug.com/435786
- DCHECK(has_complete_framebuffer_);
-
- // We will restore the current program after the dummy glBegin/End pair.
- // Ensure that we will be able to restore this state before attempting to
- // change it.
- GLint old_program_signed = 0;
- glGetIntegerv(GL_CURRENT_PROGRAM, &old_program_signed);
- GLuint old_program = static_cast<GLuint>(old_program_signed);
- if (old_program && glIsProgram(old_program)) {
- // A deleted program cannot be re-bound.
- GLint delete_status = GL_FALSE;
- glGetProgramiv(old_program, GL_DELETE_STATUS, &delete_status);
- if (delete_status == GL_TRUE)
- return;
- // A program which has had the most recent link fail cannot be re-bound.
- GLint link_status = GL_FALSE;
- glGetProgramiv(old_program, GL_LINK_STATUS, &link_status);
- if (link_status != GL_TRUE)
- return;
- }
-
- // Issue the dummy call and then restore the state.
- glUseProgram(0);
- GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- DCHECK(status == GL_FRAMEBUFFER_COMPLETE);
- if (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) {
- // These aren't present in the core profile.
- // TODO(ccameron): verify this workaround isn't still needed with
- // the core profile.
- glBegin(GL_TRIANGLES);
- glEnd();
- }
- glUseProgram(old_program);
-}
-
-unsigned int ImageTransportSurfaceFBO::GetBackingFrameBufferObject() {
- return fbo_id_;
-}
-
-bool ImageTransportSurfaceFBO::SetBackbufferAllocation(bool allocation) {
- if (backbuffer_suggested_allocation_ == allocation)
- return true;
- backbuffer_suggested_allocation_ = allocation;
- AdjustBufferAllocation();
- if (!allocation)
- storage_provider_->DiscardBackbuffer();
- return true;
-}
-
-void ImageTransportSurfaceFBO::SetFrontbufferAllocation(bool allocation) {
- if (frontbuffer_suggested_allocation_ == allocation)
- return;
- frontbuffer_suggested_allocation_ = allocation;
- AdjustBufferAllocation();
-}
-
-void ImageTransportSurfaceFBO::AdjustBufferAllocation() {
- // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is
- // free'd when both the browser and gpu processes have Unref'd the IOSurface.
- if (!backbuffer_suggested_allocation_ &&
- !frontbuffer_suggested_allocation_ &&
- has_complete_framebuffer_) {
- DestroyFramebuffer();
- } else if (backbuffer_suggested_allocation_ && !has_complete_framebuffer_) {
- AllocateOrResizeFramebuffer(pixel_size_, scale_factor_);
- }
-}
-
-gfx::SwapResult ImageTransportSurfaceFBO::SwapBuffers() {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceFBO::SwapBuffers");
- pending_swap_pixel_damage_rect_ = gfx::Rect(pixel_size_);
- return SwapBuffersInternal(gfx::Rect(pixel_size_)) ?
- gfx::SwapResult::SWAP_ACK : gfx::SwapResult::SWAP_FAILED;
-}
-
-bool ImageTransportSurfaceFBO::SwapBuffersInternal(
- const gfx::Rect& dirty_rect) {
- DCHECK(backbuffer_suggested_allocation_);
- if (!frontbuffer_suggested_allocation_)
- return true;
-
- {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceFBO::glFlush");
- glFlush();
- }
-
- // It is the responsibility of the storage provider to send the swap IPC.
- is_swap_buffers_send_pending_ = true;
- storage_provider_->SwapBuffers(dirty_rect);
-
- // The call to swapBuffers could potentially result in an immediate draw.
- // Ensure that any changes made to the context's state are restored.
- context_->RestoreStateIfDirtiedExternally();
- return true;
-}
-
-void ImageTransportSurfaceFBO::SendSwapBuffers(uint64 surface_handle,
- const gfx::Size pixel_size,
- float scale_factor) {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceFBO::SendSwapBuffers");
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
- params.surface_handle = surface_handle;
- params.size = pixel_size;
- params.damage_rect = pending_swap_pixel_damage_rect_;
- params.scale_factor = scale_factor;
- params.latency_info.swap(latency_info_);
- helper_->SendAcceleratedSurfaceBuffersSwapped(params);
- is_swap_buffers_send_pending_ = false;
- pending_swap_pixel_damage_rect_ = gfx::Rect();
-}
-
-void ImageTransportSurfaceFBO::SetRendererID(int renderer_id) {
- if (renderer_id)
- context_->share_group()->SetRendererID(renderer_id);
-}
-
-const gpu::gles2::FeatureInfo* ImageTransportSurfaceFBO::GetFeatureInfo()
- const {
- return helper_->stub()->GetFeatureInfo();
-}
-
-gfx::SwapResult ImageTransportSurfaceFBO::PostSubBuffer(int x,
- int y,
- int width,
- int height) {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceFBO::PostSubBuffer");
- pending_swap_pixel_damage_rect_.Union(gfx::Rect(x, y, width, height));
- return SwapBuffersInternal(gfx::Rect(x, y, width, height)) ?
- gfx::SwapResult::SWAP_ACK : gfx::SwapResult::SWAP_FAILED;
-}
-
-bool ImageTransportSurfaceFBO::SupportsPostSubBuffer() {
- return true;
-}
-
-gfx::Size ImageTransportSurfaceFBO::GetSize() {
- return pixel_size_;
-}
-
-void* ImageTransportSurfaceFBO::GetHandle() {
- return NULL;
-}
-
-void* ImageTransportSurfaceFBO::GetDisplay() {
- return NULL;
-}
-
-void ImageTransportSurfaceFBO::OnBufferPresented(
- const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
- TRACE_EVENT0("gpu", "ImageTransportSurfaceFBO::OnBufferPresented");
- SetRendererID(params.renderer_id);
- storage_provider_->SwapBuffersAckedByBrowser(params.disable_throttling);
-}
-
-void ImageTransportSurfaceFBO::OnResize(gfx::Size pixel_size,
- float scale_factor) {
- TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::OnResize",
- "old_size", pixel_size_.ToString(),
- "new_size", pixel_size.ToString());
- // Caching |context_| from OnMakeCurrent. It should still be current.
- DCHECK(context_->IsCurrent(this));
-
- AllocateOrResizeFramebuffer(pixel_size, scale_factor);
-}
-
-void ImageTransportSurfaceFBO::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 ImageTransportSurfaceFBO::OnWillDestroyStub() {
- helper_->stub()->RemoveDestructionObserver(this);
- Destroy();
-}
-
-void ImageTransportSurfaceFBO::DestroyFramebuffer() {
- // If we have resources to destroy, then make sure that we have a current
- // context which we can use to delete the resources.
- if (context_ || fbo_id_ || texture_id_ || depth_stencil_renderbuffer_id_) {
- DCHECK(gfx::GLContext::GetCurrent() == context_);
- DCHECK(context_->IsCurrent(this));
- DCHECK(CGLGetCurrentContext());
- }
-
- if (fbo_id_) {
- glDeleteFramebuffersEXT(1, &fbo_id_);
- fbo_id_ = 0;
- }
-
- if (texture_id_) {
- glDeleteTextures(1, &texture_id_);
- texture_id_ = 0;
- }
-
- if (depth_stencil_renderbuffer_id_) {
- glDeleteRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_);
- depth_stencil_renderbuffer_id_ = 0;
- }
-
- storage_provider_->FreeColorBufferStorage();
-
- has_complete_framebuffer_ = false;
-}
-
-void ImageTransportSurfaceFBO::AllocateOrResizeFramebuffer(
- const gfx::Size& new_pixel_size, float new_scale_factor) {
- gfx::Size new_rounded_pixel_size =
- storage_provider_->GetRoundedSize(new_pixel_size);
-
- // Only recreate the surface's storage when the rounded up size has changed,
- // or the scale factor has changed.
- bool needs_new_storage =
- !has_complete_framebuffer_ ||
- new_rounded_pixel_size != rounded_pixel_size_ ||
- new_scale_factor != scale_factor_;
-
- // Save the new storage parameters.
- pixel_size_ = new_pixel_size;
- rounded_pixel_size_ = new_rounded_pixel_size;
- scale_factor_ = new_scale_factor;
-
- if (!needs_new_storage) {
- storage_provider_->FrameSizeChanged(pixel_size_, scale_factor_);
- return;
- }
-
- TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::AllocateOrResizeFramebuffer",
- "width", new_rounded_pixel_size.width(),
- "height", new_rounded_pixel_size.height());
-
- // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
- // Mac OS X and is required for IOSurface interoperability.
- GLint previous_texture_id = 0;
-
- GLenum texture_target = GL_TEXTURE_RECTANGLE_ARB;
- GLenum texture_binding_target = GL_TEXTURE_BINDING_RECTANGLE_ARB;
- // However, the remote core animation path on the core profile will
- // be the preferred combination going forward.
- if (gfx::GetGLImplementation() ==
- gfx::kGLImplementationDesktopGLCoreProfile &&
- ui::RemoteLayerAPISupported()) {
- texture_target = GL_TEXTURE_2D;
- texture_binding_target = GL_TEXTURE_BINDING_2D;
- }
-
- glGetIntegerv(texture_binding_target, &previous_texture_id);
-
- // Free the old IO Surface first to reduce memory fragmentation.
- DestroyFramebuffer();
-
- glGenFramebuffersEXT(1, &fbo_id_);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_);
-
- glGenTextures(1, &texture_id_);
-
- glBindTexture(texture_target, texture_id_);
- glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(texture_target,
- GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(texture_target,
- GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- texture_target,
- texture_id_,
- 0);
-
- // Search through the provided attributes; if the caller has
- // requested a stencil buffer, try to get one.
-
- int32 stencil_bits =
- helper_->stub()->GetRequestedAttribute(EGL_STENCIL_SIZE);
- if (stencil_bits > 0) {
- // Create and bind the stencil buffer
- bool has_packed_depth_stencil =
- GLSurface::ExtensionsContain(
- reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
- "GL_EXT_packed_depth_stencil");
-
- if (has_packed_depth_stencil) {
- glGenRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_);
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,
- depth_stencil_renderbuffer_id_);
- glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
- rounded_pixel_size_.width(),
- rounded_pixel_size_.height());
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
- GL_STENCIL_ATTACHMENT_EXT,
- GL_RENDERBUFFER_EXT,
- depth_stencil_renderbuffer_id_);
- }
-
- // If we asked for stencil but the extension isn't present,
- // it's OK to silently fail; subsequent code will/must check
- // for the presence of a stencil buffer before attempting to
- // do stencil-based operations.
- }
-
- bool allocated_color_buffer = storage_provider_->AllocateColorBufferStorage(
- static_cast<CGLContextObj>(
- context_->GetHandle()),
- context_->GetStateWasDirtiedExternallyCallback(),
- texture_id_, rounded_pixel_size_, scale_factor_);
- if (!allocated_color_buffer) {
- DLOG(ERROR) << "Failed to allocate color buffer storage.";
- DestroyFramebuffer();
- return;
- }
-
- GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- DLOG(ERROR) << "Framebuffer was incomplete: " << status;
- DestroyFramebuffer();
- return;
- }
-
- has_complete_framebuffer_ = true;
- storage_provider_->FrameSizeChanged(pixel_size_, scale_factor_);
-
- glBindTexture(texture_target, previous_texture_id);
- // The FBO remains bound for this GL context.
-}
-
-} // namespace content
« no previous file with comments | « content/common/gpu/image_transport_surface_fbo_mac.h ('k') | content/common/gpu/image_transport_surface_iosurface_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698