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

Unified Diff: ui/gfx/surface/accelerated_surface_mac.cc

Issue 10351002: ui: Move surface/ directory out of gfx/, up to ui/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix gpu DEPS Created 8 years, 8 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
« no previous file with comments | « ui/gfx/surface/accelerated_surface_mac.h ('k') | ui/gfx/surface/accelerated_surface_win.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/surface/accelerated_surface_mac.cc
diff --git a/ui/gfx/surface/accelerated_surface_mac.cc b/ui/gfx/surface/accelerated_surface_mac.cc
deleted file mode 100644
index 6978c574ace06587c26e7655dba631b8b59b08ff..0000000000000000000000000000000000000000
--- a/ui/gfx/surface/accelerated_surface_mac.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright (c) 2011 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 "ui/gfx/surface/accelerated_surface_mac.h"
-
-#include "base/logging.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "ui/gfx/gl/gl_bindings.h"
-#include "ui/gfx/gl/gl_context.h"
-#include "ui/gfx/gl/gl_implementation.h"
-#include "ui/gfx/gl/gl_surface.h"
-#include "ui/gfx/gl/scoped_make_current.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/surface/io_surface_support_mac.h"
-
-AcceleratedSurface::AcceleratedSurface()
- : io_surface_id_(0),
- allocate_fbo_(false),
- texture_(0),
- fbo_(0) {
-}
-
-AcceleratedSurface::~AcceleratedSurface() {}
-
-bool AcceleratedSurface::Initialize(
- gfx::GLContext* share_context,
- bool allocate_fbo,
- gfx::GpuPreference gpu_preference) {
- allocate_fbo_ = allocate_fbo;
-
- // Ensure GL is initialized before trying to create an offscreen GL context.
- if (!gfx::GLSurface::InitializeOneOff())
- return false;
-
- // Drawing to IOSurfaces via OpenGL only works with Apple's GL and
- // not with the OSMesa software renderer.
- if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL &&
- gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL)
- return false;
-
- gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(
- false, gfx::Size(1, 1));
- if (!gl_surface_.get()) {
- Destroy();
- return false;
- }
-
- gfx::GLShareGroup* share_group =
- share_context ? share_context->share_group() : NULL;
-
- gl_context_ = gfx::GLContext::CreateGLContext(
- share_group,
- gl_surface_.get(),
- gpu_preference);
- if (!gl_context_.get()) {
- Destroy();
- return false;
- }
-
- // Now we're ready to handle SetSurfaceSize calls, which will
- // allocate and/or reallocate the IOSurface and associated offscreen
- // OpenGL structures for rendering.
- return true;
-}
-
-void AcceleratedSurface::Destroy() {
- // The FBO and texture objects will be destroyed when the OpenGL context,
- // and any other contexts sharing resources with it, is. We don't want to
- // make the context current one last time here just in order to delete
- // these objects.
-
- // Release the old TransportDIB in the browser.
- if (!dib_free_callback_.is_null() && transport_dib_.get()) {
- dib_free_callback_.Run(transport_dib_->id());
- }
- transport_dib_.reset();
-
- gl_context_ = NULL;
- gl_surface_ = NULL;
-}
-
-// Call after making changes to the surface which require a visual update.
-// Makes the rendering show up in other processes.
-void AcceleratedSurface::SwapBuffers() {
- if (io_surface_.get() != NULL) {
- if (allocate_fbo_) {
- // Bind and unbind the framebuffer to make changes to the
- // IOSurface show up in the other process.
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
- glFlush();
- } else {
- // Copy the current framebuffer's contents into our "live" texture.
- // Note that the current GL context might not be ours at this point!
- // This is deliberate, so that surrounding code using GL can produce
- // rendering results consumed by the AcceleratedSurface.
- // Need to save and restore OpenGL state around this call.
- GLint current_texture = 0;
- GLenum target_binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
- GLenum target = GL_TEXTURE_RECTANGLE_ARB;
- glGetIntegerv(target_binding, &current_texture);
- glBindTexture(target, texture_);
- glCopyTexSubImage2D(target, 0,
- 0, 0,
- 0, 0,
- real_surface_size_.width(),
- real_surface_size_.height());
- glBindTexture(target, current_texture);
- // This flush is absolutely essential -- it guarantees that the
- // rendering results are seen by the other process.
- glFlush();
- }
- } else if (transport_dib_.get() != NULL) {
- // Pre-Mac OS X 10.6, fetch the rendered image from the current frame
- // buffer and copy it into the TransportDIB.
- // TODO(dspringer): There are a couple of options that can speed this up.
- // First is to use async reads into a PBO, second is to use SPI that
- // allows many tasks to access the same CGSSurface.
- void* pixel_memory = transport_dib_->memory();
- if (pixel_memory) {
- // Note that glReadPixels does an implicit glFlush().
- glReadPixels(0,
- 0,
- real_surface_size_.width(),
- real_surface_size_.height(),
- GL_BGRA, // This pixel format should have no conversion.
- GL_UNSIGNED_INT_8_8_8_8_REV,
- pixel_memory);
- }
- }
-}
-
-static void AddBooleanValue(CFMutableDictionaryRef dictionary,
- const CFStringRef key,
- bool value) {
- CFDictionaryAddValue(dictionary, key,
- (value ? kCFBooleanTrue : kCFBooleanFalse));
-}
-
-static void AddIntegerValue(CFMutableDictionaryRef dictionary,
- const CFStringRef key,
- int32 value) {
- base::mac::ScopedCFTypeRef<CFNumberRef> number(
- CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
- CFDictionaryAddValue(dictionary, key, number.get());
-}
-
-// Creates a new OpenGL texture object bound to the given texture target.
-// Caller owns the returned texture.
-static GLuint CreateTexture(GLenum target) {
- GLuint texture = 0;
- glGenTextures(1, &texture);
- glBindTexture(target, texture);
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- return texture;
-}
-
-void AcceleratedSurface::AllocateRenderBuffers(GLenum target,
- const gfx::Size& size) {
- if (!texture_) {
- // Generate the texture object.
- texture_ = CreateTexture(target);
- // Generate and bind the framebuffer object.
- glGenFramebuffersEXT(1, &fbo_);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
- }
-
- // Make sure that subsequent set-up code affects the render texture.
- glBindTexture(target, texture_);
-}
-
-bool AcceleratedSurface::SetupFrameBufferObject(GLenum target) {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
- GLenum fbo_status;
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- target,
- texture_,
- 0);
- fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- return fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT;
-}
-
-gfx::Size AcceleratedSurface::ClampToValidDimensions(const gfx::Size& size) {
- return gfx::Size(std::max(size.width(), 1), std::max(size.height(), 1));
-}
-
-bool AcceleratedSurface::MakeCurrent() {
- if (!gl_context_.get())
- return false;
- return gl_context_->MakeCurrent(gl_surface_.get());
-}
-
-void AcceleratedSurface::Clear(const gfx::Rect& rect) {
- DCHECK(gl_context_->IsCurrent(gl_surface_.get()));
- glClearColor(0, 0, 0, 0);
- glViewport(0, 0, rect.width(), rect.height());
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, rect.width(), 0, rect.height(), -1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
-uint32 AcceleratedSurface::SetSurfaceSize(const gfx::Size& size) {
- if (surface_size_ == size) {
- // Return 0 to indicate to the caller that no new backing store
- // allocation occurred.
- return 0;
- }
-
- // Only support IO surfaces 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::kGLImplementationDesktopGL)
- return 0;
-
- IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
- if (!io_surface_support)
- return 0; // Caller can try using SetWindowSizeForTransportDIB().
-
- gfx::ScopedMakeCurrent make_current(gl_context_.get(), gl_surface_.get());
- if (!make_current.Succeeded())
- return 0;
-
- gfx::Size clamped_size = ClampToValidDimensions(size);
-
- // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
- // Mac OS X and is required for IOSurface interoperability.
- GLenum target = GL_TEXTURE_RECTANGLE_ARB;
- if (allocate_fbo_) {
- AllocateRenderBuffers(target, clamped_size);
- } else if (!texture_) {
- // Generate the texture object.
- texture_ = CreateTexture(target);
- }
-
- // Allocate a new IOSurface, which is the GPU resource that can be
- // shared across processes.
- base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
- properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
- AddIntegerValue(properties,
- io_surface_support->GetKIOSurfaceWidth(),
- clamped_size.width());
- AddIntegerValue(properties,
- io_surface_support->GetKIOSurfaceHeight(),
- clamped_size.height());
- AddIntegerValue(properties,
- io_surface_support->GetKIOSurfaceBytesPerElement(), 4);
- AddBooleanValue(properties,
- io_surface_support->GetKIOSurfaceIsGlobal(), true);
- // I believe we should be able to unreference the IOSurfaces without
- // synchronizing with the browser process because they are
- // ultimately reference counted by the operating system.
- io_surface_.reset(io_surface_support->IOSurfaceCreate(properties));
-
- // Don't think we need to identify a plane.
- GLuint plane = 0;
- CGLError error = io_surface_support->CGLTexImageIOSurface2D(
- static_cast<CGLContextObj>(gl_context_->GetHandle()),
- target,
- GL_RGBA,
- clamped_size.width(),
- clamped_size.height(),
- GL_BGRA,
- GL_UNSIGNED_INT_8_8_8_8_REV,
- io_surface_.get(),
- plane);
- if (error != kCGLNoError) {
- DLOG(ERROR) << "CGL error " << error << " during CGLTexImageIOSurface2D";
- }
- if (allocate_fbo_) {
- // Set up the frame buffer object.
- if (!SetupFrameBufferObject(target)) {
- DLOG(ERROR) << "Failed to set up frame buffer object";
- }
- }
- surface_size_ = size;
- real_surface_size_ = clamped_size;
-
- // Now send back an identifier for the IOSurface. We originally
- // intended to send back a mach port from IOSurfaceCreateMachPort
- // but it looks like Chrome IPC would need to be modified to
- // properly send mach ports between processes. For the time being we
- // make our IOSurfaces global and send back their identifiers. On
- // the browser process side the identifier is reconstituted into an
- // IOSurface for on-screen rendering.
- io_surface_id_ = io_surface_support->IOSurfaceGetID(io_surface_);
- return io_surface_id_;
-}
-
-uint32 AcceleratedSurface::GetSurfaceId() {
- return io_surface_id_;
-}
-
-TransportDIB::Handle AcceleratedSurface::SetTransportDIBSize(
- const gfx::Size& size) {
- if (surface_size_ == size) {
- // Return an invalid handle to indicate to the caller that no new backing
- // store allocation occurred.
- return TransportDIB::DefaultHandleValue();
- }
- surface_size_ = size;
- gfx::Size clamped_size = ClampToValidDimensions(size);
- real_surface_size_ = clamped_size;
-
- // Release the old TransportDIB in the browser.
- if (!dib_free_callback_.is_null() && transport_dib_.get()) {
- dib_free_callback_.Run(transport_dib_->id());
- }
- transport_dib_.reset();
-
- // Ask the renderer to create a TransportDIB.
- size_t dib_size =
- clamped_size.width() * 4 * clamped_size.height(); // 4 bytes per pixel.
- TransportDIB::Handle dib_handle;
- if (!dib_alloc_callback_.is_null()) {
- dib_alloc_callback_.Run(dib_size, &dib_handle);
- }
- if (!TransportDIB::is_valid_handle(dib_handle)) {
- // If the allocator fails, it means the DIB was not created in the browser,
- // so there is no need to run the deallocator here.
- return TransportDIB::DefaultHandleValue();
- }
- transport_dib_.reset(TransportDIB::Map(dib_handle));
- if (transport_dib_.get() == NULL) {
- // TODO(dspringer): if the Map() fails, should the deallocator be run so
- // that the DIB is deallocated in the browser?
- return TransportDIB::DefaultHandleValue();
- }
-
- if (allocate_fbo_) {
- DCHECK(gl_context_->IsCurrent(gl_surface_.get()));
- // Set up the render buffers and reserve enough space on the card for the
- // framebuffer texture.
- GLenum target = GL_TEXTURE_RECTANGLE_ARB;
- AllocateRenderBuffers(target, clamped_size);
- glTexImage2D(target,
- 0, // mipmap level 0
- GL_RGBA8, // internal pixel format
- clamped_size.width(),
- clamped_size.height(),
- 0, // 0 border
- GL_BGRA, // Used for consistency
- GL_UNSIGNED_INT_8_8_8_8_REV,
- NULL); // No data, just reserve room on the card.
- SetupFrameBufferObject(target);
- }
- return transport_dib_->handle();
-}
-
-void AcceleratedSurface::SetTransportDIBAllocAndFree(
- const base::Callback<void(size_t, TransportDIB::Handle*)>& allocator,
- const base::Callback<void(TransportDIB::Id)>& deallocator) {
- dib_alloc_callback_ = allocator;
- dib_free_callback_ = deallocator;
-}
« no previous file with comments | « ui/gfx/surface/accelerated_surface_mac.h ('k') | ui/gfx/surface/accelerated_surface_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698