diff options
author | tfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-03 22:45:41 +0000 |
---|---|---|
committer | tfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-03 22:45:41 +0000 |
commit | d353541f29a517a93d1b0fec023f5d12a05eade2 (patch) | |
tree | ed89daef5725a582ca4957f9b237c64113529501 /ui/gfx/surface | |
parent | 724b3891cefbc629f9db168f9b39943dabc1cfe2 (diff) | |
download | chromium_src-d353541f29a517a93d1b0fec023f5d12a05eade2.zip chromium_src-d353541f29a517a93d1b0fec023f5d12a05eade2.tar.gz chromium_src-d353541f29a517a93d1b0fec023f5d12a05eade2.tar.bz2 |
ui: Move surface/ directory out of gfx/, up to ui/.
BUG=104040
R=ben@chromium.org
TBR=brettw@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10351002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135232 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx/surface')
-rw-r--r-- | ui/gfx/surface/OWNERS | 6 | ||||
-rw-r--r-- | ui/gfx/surface/accelerated_surface_mac.cc | 363 | ||||
-rw-r--r-- | ui/gfx/surface/accelerated_surface_mac.h | 181 | ||||
-rw-r--r-- | ui/gfx/surface/accelerated_surface_win.cc | 683 | ||||
-rw-r--r-- | ui/gfx/surface/accelerated_surface_win.h | 124 | ||||
-rw-r--r-- | ui/gfx/surface/io_surface_support_mac.cc | 270 | ||||
-rw-r--r-- | ui/gfx/surface/io_surface_support_mac.h | 71 | ||||
-rw-r--r-- | ui/gfx/surface/surface.gyp | 57 | ||||
-rw-r--r-- | ui/gfx/surface/surface_export.h | 26 | ||||
-rw-r--r-- | ui/gfx/surface/transport_dib.h | 217 | ||||
-rw-r--r-- | ui/gfx/surface/transport_dib_android.cc | 101 | ||||
-rw-r--r-- | ui/gfx/surface/transport_dib_linux.cc | 141 | ||||
-rw-r--r-- | ui/gfx/surface/transport_dib_mac.cc | 98 | ||||
-rw-r--r-- | ui/gfx/surface/transport_dib_win.cc | 110 |
14 files changed, 0 insertions, 2448 deletions
diff --git a/ui/gfx/surface/OWNERS b/ui/gfx/surface/OWNERS deleted file mode 100644 index ae53906..0000000 --- a/ui/gfx/surface/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -kbr@chromium.org -pinkerton@chromium.org -stuartmorgan@chromium.org -backer@chromium.org -apatrick@chromium.org - diff --git a/ui/gfx/surface/accelerated_surface_mac.cc b/ui/gfx/surface/accelerated_surface_mac.cc deleted file mode 100644 index 6978c57..0000000 --- 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, ¤t_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; -} diff --git a/ui/gfx/surface/accelerated_surface_mac.h b/ui/gfx/surface/accelerated_surface_mac.h deleted file mode 100644 index 7cf534b..0000000 --- a/ui/gfx/surface/accelerated_surface_mac.h +++ /dev/null @@ -1,181 +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. - -#ifndef UI_GFX_SURFACE_ACCELERATED_SURFACE_MAC_H_ -#define UI_GFX_SURFACE_ACCELERATED_SURFACE_MAC_H_ -#pragma once - -#include <CoreFoundation/CoreFoundation.h> - -#include "base/callback.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/memory/scoped_ptr.h" -#include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/gl/gl_surface.h" -#include "ui/gfx/gl/gpu_preference.h" -#include "ui/gfx/rect.h" -#include "ui/gfx/size.h" -#include "ui/gfx/surface/surface_export.h" -#include "ui/gfx/surface/transport_dib.h" - -// Should not include GL headers in a header file. Forward declare these types -// instead. -typedef struct _CGLContextObject* CGLContextObj; -typedef unsigned int GLenum; -typedef unsigned int GLuint; - -namespace gfx { -class Rect; -} - -// Encapsulates an accelerated GL surface that can be shared across processes -// on systems that support it (10.6 and above). For systems that do not, it -// uses a regular dib. There will either be an IOSurface or a TransportDIB, -// never both. - -class SURFACE_EXPORT AcceleratedSurface { - public: - AcceleratedSurface(); - virtual ~AcceleratedSurface(); - - // Set up internal buffers. |share_context|, if non-NULL, is a context - // with which the internally created OpenGL context shares textures and - // other resources. |allocate_fbo| indicates whether or not this surface - // should allocate an offscreen frame buffer object (FBO) internally. If - // not, then the user is expected to allocate one. NOTE that allocating - // an FBO internally does NOT work properly with client code which uses - // OpenGL (i.e., via GLES2 command buffers), because the GLES2 - // implementation does not know to bind the accelerated surface's - // internal FBO when the default FBO is bound. |gpu_preference| indicates - // the GPU preference for the internally allocated GLContext. If - // |share_context| is non-NULL, then on platforms supporting dual GPUs, - // its GPU preference must match the passed one. Returns false upon - // failure. - bool Initialize(gfx::GLContext* share_context, - bool allocate_fbo, - gfx::GpuPreference gpu_preference); - // Tear down. Must be called before destructor to prevent leaks. - void Destroy(); - - // These methods are used only once the accelerated surface is initialized. - - // Sets the accelerated surface to the given size, creating a new one if - // the height or width changes. Returns a unique id of the IOSurface to - // which the surface is bound, or 0 if no changes were made or an error - // occurred. MakeCurrent() will have been called on the new surface. - uint32 SetSurfaceSize(const gfx::Size& size); - - // Returns the id of this surface's IOSurface, or 0 for - // transport DIB surfaces. - uint32 GetSurfaceId(); - - // Sets the GL context to be the current one for drawing. Returns true if - // it succeeded. - bool MakeCurrent(); - // Clear the surface to be transparent. Assumes the caller has already called - // MakeCurrent(). - void Clear(const gfx::Rect& rect); - // Call after making changes to the surface which require a visual update. - // Makes the rendering show up in other processes. Assumes the caller has - // already called MakeCurrent(). - // - // If this AcceleratedSurface is configured with its own FBO, then - // this call causes the color buffer to be transmitted. Otherwise, - // it causes the frame buffer of the current GL context to be copied - // either into an internal texture via glCopyTexSubImage2D or into a - // TransportDIB via glReadPixels. - // - // The size of the rectangle copied is the size last specified via - // SetSurfaceSize. If another GL context than the one this - // AcceleratedSurface contains is responsible for the production of - // the pixels, then when this entry point is called, the color - // buffer must be in a state where a glCopyTexSubImage2D or - // glReadPixels is legal. (For example, if using multisampled FBOs, - // the FBO must have been resolved into a non-multisampled color - // texture.) Additionally, in this situation, the contexts must - // share server-side GL objects, so that this AcceleratedSurface's - // texture is a legal name in the namespace of the current context. - void SwapBuffers(); - - CGLContextObj context() { - return static_cast<CGLContextObj>(gl_context_->GetHandle()); - } - - // These methods are only used when there is a transport DIB. - - // Sets the transport DIB to the given size, creating a new one if the - // height or width changes. Returns a handle to the new DIB, or a default - // handle if no changes were made. Assumes the caller has already called - // MakeCurrent(). - TransportDIB::Handle SetTransportDIBSize(const gfx::Size& size); - // Sets the methods to use for allocating and freeing memory for the - // transport DIB. - void SetTransportDIBAllocAndFree( - const base::Callback<void(size_t, TransportDIB::Handle*)>& allocator, - const base::Callback<void(TransportDIB::Id)>& deallocator); - - // Get the accelerated surface size. - gfx::Size GetSize() const { return surface_size_; } - - private: - // Helper function to generate names for the backing texture and FBO. On - // return, the resulting names can be attached to |fbo_|. |target| is - // the target type for the color buffer. - void AllocateRenderBuffers(GLenum target, const gfx::Size& size); - - // Helper function to attach the buffers previously allocated by a call to - // AllocateRenderBuffers(). On return, |fbo_| can be used for - // rendering. |target| must be the same value as used in the call to - // AllocateRenderBuffers(). Returns |true| if the resulting framebuffer - // object is valid. - bool SetupFrameBufferObject(GLenum target); - - gfx::Size ClampToValidDimensions(const gfx::Size& size); - - // The OpenGL context, and pbuffer drawable, used to transfer data - // to the shared region (IOSurface or TransportDIB). Strictly - // speaking, we do not need to allocate a GL context all of the - // time. We only need one if (a) we are using the IOSurface code - // path, or (b) if we are allocating an FBO internally. - scoped_refptr<gfx::GLSurface> gl_surface_; - scoped_refptr<gfx::GLContext> gl_context_; - // Either |io_surface_| or |transport_dib_| is a valid pointer, but not both. - // |io_surface_| is non-NULL if the IOSurface APIs are supported (Mac OS X - // 10.6 and later). - // TODO(dspringer,kbr): Should the GPU backing store be encapsulated in its - // own class so all this implementation detail is hidden? - base::mac::ScopedCFTypeRef<CFTypeRef> io_surface_; - - // The id of |io_surface_| or 0 if that's NULL. - uint32 io_surface_id_; - - // TODO(dspringer): If we end up keeping this TransportDIB mechanism, this - // should really be a scoped_ptr_malloc<>, with a deallocate functor that - // runs |dib_free_callback_|. I was not able to figure out how to - // make this work (or even compile). - scoped_ptr<TransportDIB> transport_dib_; - gfx::Size surface_size_; - // It's important to avoid allocating zero-width or zero-height - // IOSurfaces and textures on the Mac, so we clamp each to a minimum - // of 1. This is the real size of the surface; surface_size_ is what - // the user requested. - gfx::Size real_surface_size_; - // TODO(kbr): the FBO management should not be in this class at all. - // However, if it is factored out, care needs to be taken to not - // introduce another copy of the color data on the GPU; the direct - // binding of the internal texture to the IOSurface saves a copy. - bool allocate_fbo_; - // If the IOSurface code path is being used, then this texture - // object is always allocated. Otherwise, it is only allocated if - // the user requests an FBO be allocated. - GLuint texture_; - // The FBO and renderbuffer are only allocated if allocate_fbo_ is - // true. - GLuint fbo_; - // Allocate a TransportDIB in the renderer. - base::Callback<void(size_t, TransportDIB::Handle*)> dib_alloc_callback_; - base::Callback<void(TransportDIB::Id)> dib_free_callback_; -}; - -#endif // UI_GFX_SURFACE_ACCELERATED_SURFACE_MAC_H_ diff --git a/ui/gfx/surface/accelerated_surface_win.cc b/ui/gfx/surface/accelerated_surface_win.cc deleted file mode 100644 index c6d18d9..0000000 --- a/ui/gfx/surface/accelerated_surface_win.cc +++ /dev/null @@ -1,683 +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 "ui/gfx/surface/accelerated_surface_win.h" - -#include <windows.h> -#include <algorithm> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/command_line.h" -#include "base/string_number_conversions.h" -#include "base/time.h" -#include "base/debug/trace_event.h" -#include "base/file_path.h" -#include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" -#include "base/scoped_native_library.h" -#include "base/stringprintf.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" -#include "base/threading/thread_restrictions.h" -#include "base/tracked_objects.h" -#include "base/win/wrapped_window_proc.h" -#include "ui/base/win/hwnd_util.h" -#include "ui/gfx/gl/gl_switches.h" - -namespace { - -typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT sdk_version, - IDirect3D9Ex **d3d); - -const wchar_t kD3D9ModuleName[] = L"d3d9.dll"; -const char kCreate3D9DeviceExName[] = "Direct3DCreate9Ex"; - -UINT GetPresentationInterval() { - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) - return D3DPRESENT_INTERVAL_IMMEDIATE; - else - return D3DPRESENT_INTERVAL_ONE; -} - -// Calculate the number necessary to transform |source_size| into |dest_size| -// by repeating downsampling of the image of |source_size| by a factor no more -// than 2. -int GetResampleCount(const gfx::Size& source_size, const gfx::Size& dest_size) { - int width_count = 0; - int width = source_size.width(); - while (width > dest_size.width()) { - ++width_count; - width >>= 1; - } - int height_count = 0; - int height = source_size.height(); - while (height > dest_size.height()) { - ++height_count; - height >>= 1; - } - return std::max(width_count, height_count); -} - -// Returns half the size of |size| no smaller than |min_size|. -gfx::Size GetHalfSizeNoLessThan(const gfx::Size& size, - const gfx::Size& min_size) { - return gfx::Size(std::max(min_size.width(), size.width() / 2), - std::max(min_size.height(), size.height() / 2)); -} - -bool CreateTemporarySurface(IDirect3DDevice9* device, - const gfx::Size& size, - IDirect3DSurface9** surface) { - HRESULT hr = device->CreateRenderTarget( - size.width(), - size.height(), - D3DFMT_A8R8G8B8, - D3DMULTISAMPLE_NONE, - 0, - TRUE, - surface, - NULL); - return SUCCEEDED(hr); -} - -} // namespace anonymous - -// A PresentThread is a thread that is dedicated to presenting surfaces to a -// window. It owns a Direct3D device and a Direct3D query for this purpose. -class PresentThread : public base::Thread, - public base::RefCountedThreadSafe<PresentThread> { - public: - explicit PresentThread(const char* name); - - IDirect3DDevice9Ex* device() { return device_.get(); } - IDirect3DQuery9* query() { return query_.get(); } - - void InitDevice(); - void ResetDevice(); - - protected: - virtual void CleanUp(); - - private: - friend class base::RefCountedThreadSafe<PresentThread>; - - ~PresentThread(); - - base::ScopedNativeLibrary d3d_module_; - base::win::ScopedComPtr<IDirect3DDevice9Ex> device_; - - // This query is used to wait until a certain amount of progress has been - // made by the GPU and it is safe for the producer to modify its shared - // texture again. - base::win::ScopedComPtr<IDirect3DQuery9> query_; - - DISALLOW_COPY_AND_ASSIGN(PresentThread); -}; - -// There is a fixed sized pool of PresentThreads and therefore the maximum -// number of Direct3D devices owned by those threads is bounded. -class PresentThreadPool { - public: - static const int kNumPresentThreads = 4; - - PresentThreadPool(); - PresentThread* NextThread(); - - private: - int next_thread_; - scoped_refptr<PresentThread> present_threads_[kNumPresentThreads]; - - DISALLOW_COPY_AND_ASSIGN(PresentThreadPool); -}; - -// A thread safe map of presenters by surface ID that returns presenters via -// a scoped_refptr to keep them alive while they are referenced. -class AcceleratedPresenterMap { - public: - AcceleratedPresenterMap(); - scoped_refptr<AcceleratedPresenter> CreatePresenter(gfx::NativeWindow window); - void RemovePresenter(const scoped_refptr<AcceleratedPresenter>& presenter); - scoped_refptr<AcceleratedPresenter> GetPresenter(gfx::NativeWindow window); - private: - base::Lock lock_; - typedef std::map<gfx::NativeWindow, AcceleratedPresenter*> PresenterMap; - PresenterMap presenters_; - DISALLOW_COPY_AND_ASSIGN(AcceleratedPresenterMap); -}; - -base::LazyInstance<PresentThreadPool> - g_present_thread_pool = LAZY_INSTANCE_INITIALIZER; - -base::LazyInstance<AcceleratedPresenterMap> - g_accelerated_presenter_map = LAZY_INSTANCE_INITIALIZER; - -PresentThread::PresentThread(const char* name) : base::Thread(name) { -} - -void PresentThread::InitDevice() { - if (device_) - return; - - TRACE_EVENT0("surface", "PresentThread::Init"); - d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL)); - ResetDevice(); -} - -void PresentThread::ResetDevice() { - TRACE_EVENT0("surface", "PresentThread::ResetDevice"); - - // This will crash some Intel drivers but we can't render anything without - // reseting the device, which would be disappointing. - query_ = NULL; - device_ = NULL; - - Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>( - d3d_module_.GetFunctionPointer(kCreate3D9DeviceExName)); - if (!create_func) - return; - - base::win::ScopedComPtr<IDirect3D9Ex> d3d; - HRESULT hr = create_func(D3D_SDK_VERSION, d3d.Receive()); - if (FAILED(hr)) - return; - - // Any old window will do to create the device. In practice the window to - // present to is an argument to IDirect3DDevice9::Present. - HWND window = GetShellWindow(); - - D3DPRESENT_PARAMETERS parameters = { 0 }; - parameters.BackBufferWidth = 1; - parameters.BackBufferHeight = 1; - parameters.BackBufferCount = 1; - parameters.BackBufferFormat = D3DFMT_A8R8G8B8; - parameters.hDeviceWindow = window; - parameters.Windowed = TRUE; - parameters.Flags = 0; - parameters.PresentationInterval = GetPresentationInterval(); - parameters.SwapEffect = D3DSWAPEFFECT_COPY; - - hr = d3d->CreateDeviceEx( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - window, - D3DCREATE_FPU_PRESERVE | D3DCREATE_SOFTWARE_VERTEXPROCESSING | - D3DCREATE_DISABLE_PSGP_THREADING | D3DCREATE_MULTITHREADED, - ¶meters, - NULL, - device_.Receive()); - if (FAILED(hr)) - return; - - hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); - if (FAILED(hr)) - device_ = NULL; -} - -void PresentThread::CleanUp() { - // The D3D device and query are leaked because destroying the associated D3D - // query crashes some Intel drivers. - device_.Detach(); - query_.Detach(); -} - -PresentThread::~PresentThread() { - Stop(); -} - -PresentThreadPool::PresentThreadPool() : next_thread_(0) { - // Do this in the constructor so present_threads_ is initialized before any - // other thread sees it. See LazyInstance documentation. - for (int i = 0; i < kNumPresentThreads; ++i) { - present_threads_[i] = new PresentThread( - base::StringPrintf("PresentThread #%d", i).c_str()); - present_threads_[i]->Start(); - } -} - -PresentThread* PresentThreadPool::NextThread() { - next_thread_ = (next_thread_ + 1) % kNumPresentThreads; - return present_threads_[next_thread_].get(); -} - -AcceleratedPresenterMap::AcceleratedPresenterMap() { -} - -scoped_refptr<AcceleratedPresenter> AcceleratedPresenterMap::CreatePresenter( - gfx::NativeWindow window) { - scoped_refptr<AcceleratedPresenter> presenter( - new AcceleratedPresenter(window)); - - base::AutoLock locked(lock_); - DCHECK(presenters_.find(window) == presenters_.end()); - presenters_[window] = presenter.get(); - - return presenter; -} - -void AcceleratedPresenterMap::RemovePresenter( - const scoped_refptr<AcceleratedPresenter>& presenter) { - base::AutoLock locked(lock_); - for (PresenterMap::iterator it = presenters_.begin(); - it != presenters_.end(); - ++it) { - if (it->second == presenter.get()) { - presenters_.erase(it); - return; - } - } - - NOTREACHED(); -} - -scoped_refptr<AcceleratedPresenter> AcceleratedPresenterMap::GetPresenter( - gfx::NativeWindow window) { - base::AutoLock locked(lock_); - PresenterMap::iterator it = presenters_.find(window); - if (it == presenters_.end()) - return scoped_refptr<AcceleratedPresenter>(); - - return it->second; -} - -AcceleratedPresenter::AcceleratedPresenter(gfx::NativeWindow window) - : present_thread_(g_present_thread_pool.Pointer()->NextThread()), - window_(window), - event_(false, false) { -} - -scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( - gfx::NativeWindow window) { - return g_accelerated_presenter_map.Pointer()->GetPresenter(window); -} - -void AcceleratedPresenter::AsyncPresentAndAcknowledge( - const gfx::Size& size, - int64 surface_handle, - const base::Callback<void(bool)>& completion_task) { - if (!surface_handle) { - completion_task.Run(true); - return; - } - - present_thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, - this, - size, - surface_handle, - completion_task)); -} - -bool AcceleratedPresenter::Present() { - TRACE_EVENT0("surface", "Present"); - - bool result; - - present_thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&AcceleratedPresenter::DoPresent, - this, - &result)); - // http://crbug.com/125391 - base::ThreadRestrictions::ScopedAllowWait allow_wait; - event_.Wait(); - return result; -} - -void AcceleratedPresenter::DoPresent(bool* result) -{ - *result = DoRealPresent(); - event_.Signal(); -} - -bool AcceleratedPresenter::DoRealPresent() -{ - TRACE_EVENT0("surface", "DoRealPresent"); - HRESULT hr; - - base::AutoLock locked(lock_); - - // Signal the caller to recomposite if the presenter has been suspended or no - // surface has ever been presented. - if (!swap_chain_) - return false; - - // If invalidated, do nothing. The window is gone. - if (!window_) - return true; - - RECT rect = { - 0, 0, - size_.width(), size_.height() - }; - - { - TRACE_EVENT0("surface", "PresentEx"); - hr = swap_chain_->Present(&rect, - &rect, - window_, - NULL, - D3DPRESENT_INTERVAL_IMMEDIATE); - if (FAILED(hr)) - return false; - } - - return true; -} - -bool AcceleratedPresenter::CopyTo(const gfx::Size& size, void* buf) { - base::AutoLock locked(lock_); - - if (!swap_chain_) - return false; - - base::win::ScopedComPtr<IDirect3DSurface9> back_buffer; - HRESULT hr = swap_chain_->GetBackBuffer(0, - D3DBACKBUFFER_TYPE_MONO, - back_buffer.Receive()); - if (FAILED(hr)) - return false; - - D3DSURFACE_DESC desc; - hr = back_buffer->GetDesc(&desc); - if (FAILED(hr)) - return false; - - const gfx::Size back_buffer_size(desc.Width, desc.Height); - if (back_buffer_size.IsEmpty()) - return false; - - // Set up intermediate buffers needed for downsampling. - const int resample_count = - GetResampleCount(gfx::Size(desc.Width, desc.Height), size); - base::win::ScopedComPtr<IDirect3DSurface9> final_surface; - base::win::ScopedComPtr<IDirect3DSurface9> temp_buffer[2]; - if (resample_count == 0) - final_surface = back_buffer; - if (resample_count > 0) { - if (!CreateTemporarySurface(present_thread_->device(), - size, - final_surface.Receive())) - return false; - } - const gfx::Size half_size = GetHalfSizeNoLessThan(back_buffer_size, size); - if (resample_count > 1) { - if (!CreateTemporarySurface(present_thread_->device(), - half_size, - temp_buffer[0].Receive())) - return false; - } - if (resample_count > 2) { - const gfx::Size quarter_size = GetHalfSizeNoLessThan(half_size, size); - if (!CreateTemporarySurface(present_thread_->device(), - quarter_size, - temp_buffer[1].Receive())) - return false; - } - - // Repeat downsampling the surface until its size becomes identical to - // |size|. We keep the factor of each downsampling no more than two because - // using a factor more than two can introduce aliasing. - gfx::Size read_size = back_buffer_size; - gfx::Size write_size = half_size; - int read_buffer_index = 1; - int write_buffer_index = 0; - for (int i = 0; i < resample_count; ++i) { - base::win::ScopedComPtr<IDirect3DSurface9> read_buffer = - (i == 0) ? back_buffer : temp_buffer[read_buffer_index]; - base::win::ScopedComPtr<IDirect3DSurface9> write_buffer = - (i == resample_count - 1) ? final_surface : - temp_buffer[write_buffer_index]; - RECT read_rect = {0, 0, read_size.width(), read_size.height()}; - RECT write_rect = {0, 0, write_size.width(), write_size.height()}; - hr = present_thread_->device()->StretchRect(read_buffer, - &read_rect, - write_buffer, - &write_rect, - D3DTEXF_LINEAR); - if (FAILED(hr)) - return false; - read_size = write_size; - write_size = GetHalfSizeNoLessThan(write_size, size); - std::swap(read_buffer_index, write_buffer_index); - } - - DCHECK(size == read_size); - - base::win::ScopedComPtr<IDirect3DSurface9> temp_surface; - HANDLE handle = reinterpret_cast<HANDLE>(buf); - hr = present_thread_->device()->CreateOffscreenPlainSurface( - size.width(), - size.height(), - D3DFMT_A8R8G8B8, - D3DPOOL_SYSTEMMEM, - temp_surface.Receive(), - &handle); - if (FAILED(hr)) - return false; - - // Copy the data in the temporary buffer to the surface backed by |buf|. - hr = present_thread_->device()->GetRenderTargetData(final_surface, - temp_surface); - if (FAILED(hr)) - return false; - - return true; -} - -void AcceleratedPresenter::Suspend() { - present_thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&AcceleratedPresenter::DoSuspend, - this)); -} - -void AcceleratedPresenter::ReleaseSurface() { - present_thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&AcceleratedPresenter::DoReleaseSurface, - this)); -} - -void AcceleratedPresenter::Invalidate() { - // Make any pending or future presentation tasks do nothing. Once the last - // last pending task has been ignored, the reference count on the presenter - // will go to zero and the presenter, and potentially also the present thread - // it has a reference count on, will be destroyed. - base::AutoLock locked(lock_); - window_ = NULL; -} - -AcceleratedPresenter::~AcceleratedPresenter() { -} - -static base::TimeDelta GetSwapDelay() { - CommandLine* cmd_line = CommandLine::ForCurrentProcess(); - int delay = 0; - if (cmd_line->HasSwitch(switches::kGpuSwapDelay)) { - base::StringToInt(cmd_line->GetSwitchValueNative( - switches::kGpuSwapDelay).c_str(), &delay); - } - return base::TimeDelta::FromMilliseconds(delay); -} - -void AcceleratedPresenter::DoPresentAndAcknowledge( - const gfx::Size& size, - int64 surface_handle, - const base::Callback<void(bool)>& completion_task) { - TRACE_EVENT1( - "surface", "DoPresentAndAcknowledge", "surface_handle", surface_handle); - - HRESULT hr; - - base::AutoLock locked(lock_); - - // Initialize the device lazily since calling Direct3D can crash bots. - present_thread_->InitDevice(); - - if (!present_thread_->device()) { - if (!completion_task.is_null()) - completion_task.Run(false); - return; - } - - // Ensure the task is always run and while the lock is taken. - base::ScopedClosureRunner scoped_completion_runner(base::Bind(completion_task, - true)); - - // If invalidated, do nothing, the window is gone. - if (!window_) - return; - - // Round up size so the swap chain is not continuously resized with the - // surface, which could lead to memory fragmentation. - const int kRound = 64; - gfx::Size quantized_size( - std::max(1, (size.width() + kRound - 1) / kRound * kRound), - std::max(1, (size.height() + kRound - 1) / kRound * kRound)); - - // Ensure the swap chain exists and is the same size (rounded up) as the - // surface to be presented. - if (!swap_chain_ || size_ != quantized_size) { - TRACE_EVENT0("surface", "CreateAdditionalSwapChain"); - size_ = quantized_size; - - D3DPRESENT_PARAMETERS parameters = { 0 }; - parameters.BackBufferWidth = quantized_size.width(); - parameters.BackBufferHeight = quantized_size.height(); - parameters.BackBufferCount = 1; - parameters.BackBufferFormat = D3DFMT_A8R8G8B8; - parameters.hDeviceWindow = GetShellWindow(); - parameters.Windowed = TRUE; - parameters.Flags = 0; - parameters.PresentationInterval = GetPresentationInterval(); - parameters.SwapEffect = D3DSWAPEFFECT_COPY; - - swap_chain_ = NULL; - HRESULT hr = present_thread_->device()->CreateAdditionalSwapChain( - ¶meters, - swap_chain_.Receive()); - if (FAILED(hr)) - return; - } - - if (!source_texture_.get()) { - TRACE_EVENT0("surface", "CreateTexture"); - HANDLE handle = reinterpret_cast<HANDLE>(surface_handle); - hr = present_thread_->device()->CreateTexture(size.width(), - size.height(), - 1, - D3DUSAGE_RENDERTARGET, - D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, - source_texture_.Receive(), - &handle); - if (FAILED(hr)) - return; - } - - base::win::ScopedComPtr<IDirect3DSurface9> source_surface; - hr = source_texture_->GetSurfaceLevel(0, source_surface.Receive()); - if (FAILED(hr)) - return; - - base::win::ScopedComPtr<IDirect3DSurface9> dest_surface; - hr = swap_chain_->GetBackBuffer(0, - D3DBACKBUFFER_TYPE_MONO, - dest_surface.Receive()); - if (FAILED(hr)) - return; - - RECT rect = { - 0, 0, - size.width(), size.height() - }; - - { - TRACE_EVENT0("surface", "StretchRect"); - hr = present_thread_->device()->StretchRect(source_surface, - &rect, - dest_surface, - &rect, - D3DTEXF_NONE); - if (FAILED(hr)) - return; - } - - hr = present_thread_->query()->Issue(D3DISSUE_END); - if (FAILED(hr)) - return; - - // Flush so the StretchRect can be processed by the GPU while the window is - // being resized. - present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); - - ::SetWindowPos( - window_, - NULL, - 0, 0, - size.width(), size.height(), - SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE |SWP_NOOWNERZORDER | - SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOSENDCHANGING | - SWP_ASYNCWINDOWPOS | SWP_NOZORDER); - - // Wait for the StretchRect to complete before notifying the GPU process - // that it is safe to write to its backing store again. - { - TRACE_EVENT0("surface", "spin"); - do { - hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); - - if (hr == S_FALSE) - Sleep(1); - } while (hr == S_FALSE); - } - - static const base::TimeDelta swap_delay = GetSwapDelay(); - if (swap_delay.ToInternalValue()) - base::PlatformThread::Sleep(swap_delay); - - { - TRACE_EVENT0("surface", "Present"); - hr = swap_chain_->Present(&rect, &rect, window_, NULL, 0); - if (FAILED(hr) && - FAILED(present_thread_->device()->CheckDeviceState(window_))) { - present_thread_->ResetDevice(); - } - } -} - -void AcceleratedPresenter::DoSuspend() { - base::AutoLock locked(lock_); - swap_chain_ = NULL; -} - -void AcceleratedPresenter::DoReleaseSurface() { - base::AutoLock locked(lock_); - source_texture_.Release(); -} - -AcceleratedSurface::AcceleratedSurface(gfx::NativeWindow window) - : presenter_(g_accelerated_presenter_map.Pointer()->CreatePresenter( - window)) { -} - -AcceleratedSurface::~AcceleratedSurface() { - g_accelerated_presenter_map.Pointer()->RemovePresenter(presenter_); - presenter_->Invalidate(); -} - -bool AcceleratedSurface::Present() { - return presenter_->Present(); -} - -bool AcceleratedSurface::CopyTo(const gfx::Size& size, void* buf) { - return presenter_->CopyTo(size, buf); -} - -void AcceleratedSurface::Suspend() { - presenter_->Suspend(); -} diff --git a/ui/gfx/surface/accelerated_surface_win.h b/ui/gfx/surface/accelerated_surface_win.h deleted file mode 100644 index 8a8da98..0000000 --- a/ui/gfx/surface/accelerated_surface_win.h +++ /dev/null @@ -1,124 +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. - -#ifndef UI_GFX_SURFACE_ACCELERATED_SURFACE_WIN_H_ -#define UI_GFX_SURFACE_ACCELERATED_SURFACE_WIN_H_ -#pragma once - -#include <d3d9.h> - -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" -#include "base/synchronization/lock.h" -#include "base/synchronization/waitable_event.h" -#include "base/win/scoped_comptr.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/gfx/size.h" -#include "ui/gfx/surface/surface_export.h" - -class PresentThread; - -class SURFACE_EXPORT AcceleratedPresenter - : public base::RefCountedThreadSafe<AcceleratedPresenter> { - public: - typedef base::Callback<void(bool)> CompletionTaskl; - - explicit AcceleratedPresenter(gfx::NativeWindow window); - - // Returns a thread safe reference to the presenter for the given window or - // null is no such presenter exists. The thread safe refptr ensures the - // presenter will not be destroyed. This can be called on any thread. - static scoped_refptr<AcceleratedPresenter> GetForWindow( - gfx::NativeWindow window); - - // Schedule a frame to be presented. The completion callback will be invoked - // when it is safe to write to the surface on another thread. The lock for - // this surface will be held while the completion callback runs. This can be - // called on any thread. - void AsyncPresentAndAcknowledge( - const gfx::Size& size, - int64 surface_handle, - const base::Callback<void(bool)>& completion_task); - - // Schedule the presenter to free all its resources. This can be called on any - // thread. - void Suspend(); - - // Schedule the presenter to release its reference to the shared surface. - void ReleaseSurface(); - - // The public member functions are called on the main thread. - bool Present(); - bool CopyTo(const gfx::Size& size, void* buf); - void Invalidate(); - - private: - friend class base::RefCountedThreadSafe<AcceleratedPresenter>; - - ~AcceleratedPresenter(); - - // These member functions are called on the PresentThread with which the - // presenter has affinity. - void DoPresentAndAcknowledge( - const gfx::Size& size, - int64 surface_handle, - const base::Callback<void(bool)>& completion_task); - void DoSuspend(); - void DoPresent(bool* presented); - bool DoRealPresent(); - void DoReleaseSurface(); - - // The thread with which this presenter has affinity. - PresentThread* const present_thread_; - - // The window that is presented to. - gfx::NativeWindow window_; - - // The lock is taken while any thread is calling the object, except those that - // simply post from the main thread to the present thread via the immutable - // present_thread_ member. - base::Lock lock_; - - // UI thread can wait on this event to ensure a present is finished. - base::WaitableEvent event_; - - // The current size of the swap chain. This is only accessed on the thread - // with which the surface has affinity. - gfx::Size size_; - - // This is a shared texture that is being presented from. - base::win::ScopedComPtr<IDirect3DTexture9> source_texture_; - - // The swap chain is presented to the child window. Copy semantics - // are used so it is possible to represent it to quickly validate the window. - base::win::ScopedComPtr<IDirect3DSwapChain9> swap_chain_; - - DISALLOW_COPY_AND_ASSIGN(AcceleratedPresenter); -}; - -class SURFACE_EXPORT AcceleratedSurface { - public: - AcceleratedSurface(gfx::NativeWindow window); - ~AcceleratedSurface(); - - // Synchronously present a frame with no acknowledgement. - bool Present(); - - // Copies the surface data to |buf|. The image data is transformed so that it - // fits in |size|. - // Caller must ensure that |buf| is allocated with the size no less than - // |4 * size.width() * size.height()| bytes. - bool CopyTo(const gfx::Size& size, void* buf); - - // Temporarily release resources until a new surface is asynchronously - // presented. Present will not be able to represent the last surface after - // calling this and will return false. - void Suspend(); - - private: - const scoped_refptr<AcceleratedPresenter> presenter_; - DISALLOW_COPY_AND_ASSIGN(AcceleratedSurface); -}; - -#endif // UI_GFX_SURFACE_ACCELERATED_SURFACE_WIN_H_ diff --git a/ui/gfx/surface/io_surface_support_mac.cc b/ui/gfx/surface/io_surface_support_mac.cc deleted file mode 100644 index df08217..0000000 --- a/ui/gfx/surface/io_surface_support_mac.cc +++ /dev/null @@ -1,270 +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 <dlfcn.h> - -#include "base/memory/singleton.h" -#include "ui/gfx/surface/io_surface_support_mac.h" - -typedef CFTypeRef (*IOSurfaceCreateProcPtr)(CFDictionaryRef properties); -typedef uint32 (*IOSurfaceGetIDProcPtr)(CFTypeRef io_surface); -typedef CFTypeRef (*IOSurfaceLookupProcPtr)(uint32 io_surface_id); -typedef mach_port_t (*IOSurfaceCreateMachPortProcPtr)(CFTypeRef io_surface); -typedef CFTypeRef (*IOSurfaceLookupFromMachPortProcPtr)(mach_port_t port); -typedef size_t (*IOSurfaceGetWidthPtr)(CFTypeRef io_surface); -typedef size_t (*IOSurfaceGetHeightPtr)(CFTypeRef io_surface); -typedef CGLError (*CGLTexImageIOSurface2DProcPtr)(CGLContextObj ctx, - GLenum target, - GLenum internal_format, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - CFTypeRef io_surface, - GLuint plane); - -class IOSurfaceSupportImpl : public IOSurfaceSupport { - public: - static IOSurfaceSupportImpl* GetInstance(); - - bool InitializedSuccessfully() { - return initialized_successfully_; - } - - virtual CFStringRef GetKIOSurfaceWidth(); - virtual CFStringRef GetKIOSurfaceHeight(); - virtual CFStringRef GetKIOSurfaceBytesPerElement(); - virtual CFStringRef GetKIOSurfaceIsGlobal(); - - virtual CFTypeRef IOSurfaceCreate(CFDictionaryRef properties); - virtual uint32 IOSurfaceGetID(CFTypeRef io_surface); - virtual CFTypeRef IOSurfaceLookup(uint32 io_surface_id); - virtual mach_port_t IOSurfaceCreateMachPort(CFTypeRef io_surface); - virtual CFTypeRef IOSurfaceLookupFromMachPort(mach_port_t port); - - virtual size_t IOSurfaceGetWidth(CFTypeRef io_surface); - virtual size_t IOSurfaceGetHeight(CFTypeRef io_surface); - - virtual CGLError CGLTexImageIOSurface2D(CGLContextObj ctx, - GLenum target, - GLenum internal_format, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - CFTypeRef io_surface, - GLuint plane); - - private: - IOSurfaceSupportImpl(); - ~IOSurfaceSupportImpl(); - - void* iosurface_handle_; - void* opengl_handle_; - CFStringRef k_io_surface_width_; - CFStringRef k_io_surface_height_; - CFStringRef k_io_surface_bytes_per_element_; - CFStringRef k_io_surface_is_global_; - IOSurfaceCreateProcPtr io_surface_create_; - IOSurfaceGetIDProcPtr io_surface_get_id_; - IOSurfaceLookupProcPtr io_surface_lookup_; - IOSurfaceCreateMachPortProcPtr io_surface_create_mach_port_; - IOSurfaceLookupFromMachPortProcPtr io_surface_lookup_from_mach_port_; - IOSurfaceGetWidthPtr io_surface_get_width_; - IOSurfaceGetHeightPtr io_surface_get_height_; - CGLTexImageIOSurface2DProcPtr cgl_tex_image_io_surface_2d_; - bool initialized_successfully_; - - friend struct DefaultSingletonTraits<IOSurfaceSupportImpl>; - DISALLOW_COPY_AND_ASSIGN(IOSurfaceSupportImpl); -}; - -IOSurfaceSupportImpl* IOSurfaceSupportImpl::GetInstance() { - IOSurfaceSupportImpl* impl = Singleton<IOSurfaceSupportImpl>::get(); - if (impl->InitializedSuccessfully()) - return impl; - return NULL; -} - -CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceWidth() { - return k_io_surface_width_; -} - -CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceHeight() { - return k_io_surface_height_; -} - -CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceBytesPerElement() { - return k_io_surface_bytes_per_element_; -} - -CFStringRef IOSurfaceSupportImpl::GetKIOSurfaceIsGlobal() { - return k_io_surface_is_global_; -} - -CFTypeRef IOSurfaceSupportImpl::IOSurfaceCreate(CFDictionaryRef properties) { - return io_surface_create_(properties); -} - -uint32 IOSurfaceSupportImpl::IOSurfaceGetID( - CFTypeRef io_surface) { - return io_surface_get_id_(io_surface); -} - -CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookup(uint32 io_surface_id) { - return io_surface_lookup_(io_surface_id); -} - -mach_port_t IOSurfaceSupportImpl::IOSurfaceCreateMachPort( - CFTypeRef io_surface) { - return io_surface_create_mach_port_(io_surface); -} - -CFTypeRef IOSurfaceSupportImpl::IOSurfaceLookupFromMachPort(mach_port_t port) { - return io_surface_lookup_from_mach_port_(port); -} - -size_t IOSurfaceSupportImpl::IOSurfaceGetWidth(CFTypeRef io_surface) { - return io_surface_get_width_(io_surface); -} - -size_t IOSurfaceSupportImpl::IOSurfaceGetHeight(CFTypeRef io_surface) { - return io_surface_get_height_(io_surface); -} - - -CGLError IOSurfaceSupportImpl::CGLTexImageIOSurface2D(CGLContextObj ctx, - GLenum target, - GLenum internal_format, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - CFTypeRef io_surface, - GLuint plane) { - return cgl_tex_image_io_surface_2d_(ctx, - target, - internal_format, - width, - height, - format, - type, - io_surface, - plane); -} - -IOSurfaceSupportImpl::IOSurfaceSupportImpl() - : iosurface_handle_(NULL), - opengl_handle_(NULL), - k_io_surface_width_(NULL), - k_io_surface_height_(NULL), - k_io_surface_bytes_per_element_(NULL), - k_io_surface_is_global_(NULL), - io_surface_create_(NULL), - io_surface_get_id_(NULL), - io_surface_lookup_(NULL), - io_surface_create_mach_port_(NULL), - io_surface_lookup_from_mach_port_(NULL), - io_surface_get_width_(NULL), - io_surface_get_height_(NULL), - cgl_tex_image_io_surface_2d_(NULL), - initialized_successfully_(false) { - iosurface_handle_ = dlopen( - "/System/Library/Frameworks/IOSurface.framework/IOSurface", - RTLD_LAZY | RTLD_LOCAL); - if (!iosurface_handle_) - return; - opengl_handle_ = dlopen( - "/System/Library/Frameworks/OpenGL.framework/OpenGL", - RTLD_LAZY | RTLD_LOCAL); - if (!opengl_handle_) { - dlclose(iosurface_handle_); - iosurface_handle_ = NULL; - return; - } - - void* surface_width_ptr = dlsym(iosurface_handle_, "kIOSurfaceWidth"); - void* surface_height_ptr = dlsym(iosurface_handle_, "kIOSurfaceHeight"); - void* surface_bytes_per_element_ptr = - dlsym(iosurface_handle_, "kIOSurfaceBytesPerElement"); - void* surface_is_global_ptr = - dlsym(iosurface_handle_, "kIOSurfaceIsGlobal"); - void* surface_create_ptr = dlsym(iosurface_handle_, "IOSurfaceCreate"); - void* surface_get_id_ptr = dlsym(iosurface_handle_, "IOSurfaceGetID"); - void* surface_lookup_ptr = dlsym(iosurface_handle_, "IOSurfaceLookup"); - void* surface_create_mach_port_ptr = - dlsym(iosurface_handle_, "IOSurfaceCreateMachPort"); - void* surface_lookup_from_mach_port_ptr = - dlsym(iosurface_handle_, "IOSurfaceLookupFromMachPort"); - void* io_surface_get_width_ptr = - dlsym(iosurface_handle_, "IOSurfaceGetWidth"); - void* io_surface_get_height_ptr = - dlsym(iosurface_handle_, "IOSurfaceGetHeight"); - void* tex_image_io_surface_2d_ptr = - dlsym(opengl_handle_, "CGLTexImageIOSurface2D"); - if (!surface_width_ptr || - !surface_height_ptr || - !surface_bytes_per_element_ptr || - !surface_is_global_ptr || - !surface_create_ptr || - !surface_get_id_ptr || - !surface_lookup_ptr || - !surface_create_mach_port_ptr || - !surface_lookup_from_mach_port_ptr || - !io_surface_get_width_ptr || - !io_surface_get_height_ptr || - !tex_image_io_surface_2d_ptr) { - dlclose(iosurface_handle_); - iosurface_handle_ = NULL; - dlclose(opengl_handle_); - opengl_handle_ = NULL; - return; - } - - k_io_surface_width_ = *static_cast<CFStringRef*>(surface_width_ptr); - k_io_surface_height_ = *static_cast<CFStringRef*>(surface_height_ptr); - k_io_surface_bytes_per_element_ = - *static_cast<CFStringRef*>(surface_bytes_per_element_ptr); - k_io_surface_is_global_ = *static_cast<CFStringRef*>(surface_is_global_ptr); - io_surface_create_ = reinterpret_cast<IOSurfaceCreateProcPtr>( - surface_create_ptr); - io_surface_get_id_ = - reinterpret_cast<IOSurfaceGetIDProcPtr>(surface_get_id_ptr); - io_surface_lookup_ = - reinterpret_cast<IOSurfaceLookupProcPtr>(surface_lookup_ptr); - io_surface_create_mach_port_ = - reinterpret_cast<IOSurfaceCreateMachPortProcPtr>( - surface_create_mach_port_ptr); - io_surface_lookup_from_mach_port_ = - reinterpret_cast<IOSurfaceLookupFromMachPortProcPtr>( - surface_lookup_from_mach_port_ptr); - io_surface_get_width_ = - reinterpret_cast<IOSurfaceGetWidthPtr>( - io_surface_get_width_ptr); - io_surface_get_height_ = - reinterpret_cast<IOSurfaceGetHeightPtr>( - io_surface_get_height_ptr); - cgl_tex_image_io_surface_2d_ = - reinterpret_cast<CGLTexImageIOSurface2DProcPtr>( - tex_image_io_surface_2d_ptr); - initialized_successfully_ = true; -} - -IOSurfaceSupportImpl::~IOSurfaceSupportImpl() { - if (iosurface_handle_) - dlclose(iosurface_handle_); - if (opengl_handle_) - dlclose(opengl_handle_); -} - -IOSurfaceSupport* IOSurfaceSupport::Initialize() { - return IOSurfaceSupportImpl::GetInstance(); -} - -IOSurfaceSupport::IOSurfaceSupport() { -} - -IOSurfaceSupport::~IOSurfaceSupport() { -} - diff --git a/ui/gfx/surface/io_surface_support_mac.h b/ui/gfx/surface/io_surface_support_mac.h deleted file mode 100644 index b49dbfe..0000000 --- a/ui/gfx/surface/io_surface_support_mac.h +++ /dev/null @@ -1,71 +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. - -#ifndef UI_GFX_SURFACE_IO_SURFACE_SUPPORT_MAC_H_ -#define UI_GFX_SURFACE_IO_SURFACE_SUPPORT_MAC_H_ -#pragma once - -#include <CoreFoundation/CoreFoundation.h> -#include <mach/mach.h> -#include <OpenGL/OpenGL.h> - -#include "base/basictypes.h" -#include "ui/gfx/surface/surface_export.h" - -// This Mac OS X-specific class provides dynamically-linked access to -// IOSurface.framework, which is only available on 10.6 and later. -// Since Chromium is built on 10.5 we must dynamically look up all of -// the entry points we need in this framework. - -// See IOSurface/IOSurfaceAPI.h and OpenGL/CGLIOSurface.h on 10.6 for -// documentation of the fields and methods of this class. - -class SURFACE_EXPORT IOSurfaceSupport { - public: - // Returns an instance of the IOSurfaceSupport class if the - // operating system supports it, NULL otherwise. It is safe to call - // this multiple times. - static IOSurfaceSupport* Initialize(); - - virtual CFStringRef GetKIOSurfaceWidth() = 0; - virtual CFStringRef GetKIOSurfaceHeight() = 0; - virtual CFStringRef GetKIOSurfaceBytesPerElement() = 0; - virtual CFStringRef GetKIOSurfaceIsGlobal() = 0; - - virtual CFTypeRef IOSurfaceCreate(CFDictionaryRef properties) = 0; - - // The following two APIs assume the IOSurface was created with the - // kIOSurfaceIsGlobal key set to true - virtual uint32 IOSurfaceGetID(CFTypeRef io_surface) = 0; - virtual CFTypeRef IOSurfaceLookup(uint32 io_surface_id) = 0; - - // The following two APIs are more robust and secure, but - // unfortunately it looks like it will be a lot of work to correctly - // transmit a mach port from process to process (possibly requiring - // a side channel for or extension of the Chrome IPC mechanism) - virtual mach_port_t IOSurfaceCreateMachPort(CFTypeRef io_surface) = 0; - virtual CFTypeRef IOSurfaceLookupFromMachPort(mach_port_t port) = 0; - - virtual size_t IOSurfaceGetWidth(CFTypeRef io_surface) = 0; - virtual size_t IOSurfaceGetHeight(CFTypeRef io_surface) = 0; - - virtual CGLError CGLTexImageIOSurface2D(CGLContextObj ctx, - GLenum target, - GLenum internal_format, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - CFTypeRef io_surface, - GLuint plane) = 0; - - protected: - IOSurfaceSupport(); - virtual ~IOSurfaceSupport(); - - DISALLOW_COPY_AND_ASSIGN(IOSurfaceSupport); -}; - -#endif // UI_GFX_SURFACE_IO_SURFACE_SUPPORT_MAC_H_ - diff --git a/ui/gfx/surface/surface.gyp b/ui/gfx/surface/surface.gyp deleted file mode 100644 index e11c492..0000000 --- a/ui/gfx/surface/surface.gyp +++ /dev/null @@ -1,57 +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. - -{ - 'variables': { - 'chromium_code': 1, - }, - - 'target_defaults': { - 'conditions': [ - ['use_x11 == 1', { - 'include_dirs': [ - '<(DEPTH)/third_party/angle/include', - ], - }], - ], - }, - 'targets': [ - { - 'target_name': 'surface', - 'type': '<(component)', - 'dependencies': [ - '<(DEPTH)/base/base.gyp:base', - '<(DEPTH)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', - '<(DEPTH)/skia/skia.gyp:skia', - '<(DEPTH)/ui/gfx/gl/gl.gyp:gl', - '<(DEPTH)/ui/ui.gyp:ui', - ], - 'sources': [ - 'accelerated_surface_mac.cc', - 'accelerated_surface_mac.h', - 'accelerated_surface_win.cc', - 'accelerated_surface_win.h', - 'io_surface_support_mac.cc', - 'io_surface_support_mac.h', - 'surface_export.h', - 'transport_dib.h', - 'transport_dib_android.cc', - 'transport_dib_linux.cc', - 'transport_dib_mac.cc', - 'transport_dib_win.cc', - ], - 'defines': [ - 'SURFACE_IMPLEMENTATION', - ], - 'conditions': [ - ['use_aura==1', { - 'sources/': [ - ['exclude', 'accelerated_surface_win.cc'], - ['exclude', 'accelerated_surface_win.h'], - ], - }], - ], - }, - ], -} diff --git a/ui/gfx/surface/surface_export.h b/ui/gfx/surface/surface_export.h deleted file mode 100644 index 9b8420a..0000000 --- a/ui/gfx/surface/surface_export.h +++ /dev/null @@ -1,26 +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. - -#ifndef UI_GFX_SURFACE_SURFACE_EXPORT_H_ -#define UI_GFX_SURFACE_SURFACE_EXPORT_H_ -#pragma once - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(SURFACE_IMPLEMENTATION) -#define SURFACE_EXPORT __declspec(dllexport) -#else -#define SURFACE_EXPORT __declspec(dllimport) -#endif // defined(SURFACE_IMPLEMENTATION) - -#else // defined(WIN32) -#define SURFACE_EXPORT __attribute__((visibility("default"))) -#endif - -#else // defined(COMPONENT_BUILD) -#define SURFACE_EXPORT -#endif - -#endif // UI_GFX_SURFACE_SURFACE_EXPORT_H_ diff --git a/ui/gfx/surface/transport_dib.h b/ui/gfx/surface/transport_dib.h deleted file mode 100644 index 4e4d62a..0000000 --- a/ui/gfx/surface/transport_dib.h +++ /dev/null @@ -1,217 +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. - -#ifndef UI_GFX_SURFACE_TRANSPORT_DIB_H_ -#define UI_GFX_SURFACE_TRANSPORT_DIB_H_ -#pragma once - -#include "base/basictypes.h" -#include "ui/gfx/surface/surface_export.h" - -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_ANDROID) -#include "base/shared_memory.h" -#endif - -#if defined(OS_WIN) -#include <windows.h> -#elif defined(USE_X11) -#include "ui/base/x/x11_util.h" -#endif - -namespace skia { -class PlatformCanvas; -} - -// ----------------------------------------------------------------------------- -// A TransportDIB is a block of memory that is used to transport pixels -// between processes: from the renderer process to the browser, and -// between renderer and plugin processes. -// ----------------------------------------------------------------------------- -class SURFACE_EXPORT TransportDIB { - public: - ~TransportDIB(); - - // Two typedefs are defined. A Handle is the type which can be sent over - // the wire so that the remote side can map the transport DIB. The Id typedef - // is sufficient to identify the transport DIB when you know that the remote - // side already may have it mapped. -#if defined(OS_WIN) - typedef HANDLE Handle; - // On Windows, the Id type includes a sequence number (epoch) to solve an ABA - // issue: - // 1) Process A creates a transport DIB with HANDLE=1 and sends to B. - // 2) Process B maps the transport DIB and caches 1 -> DIB. - // 3) Process A closes the transport DIB and creates a new one. The new DIB - // is also assigned HANDLE=1. - // 4) Process A sends the Handle to B, but B incorrectly believes that it - // already has it cached. - struct HandleAndSequenceNum { - HandleAndSequenceNum() - : handle(NULL), - sequence_num(0) { - } - - HandleAndSequenceNum(HANDLE h, uint32 seq_num) - : handle(h), - sequence_num(seq_num) { - } - - bool operator<(const HandleAndSequenceNum& other) const { - // Use the lexicographic order on the tuple <handle, sequence_num>. - if (other.handle != handle) - return other.handle < handle; - return other.sequence_num < sequence_num; - } - - HANDLE handle; - uint32 sequence_num; - }; - typedef HandleAndSequenceNum Id; - - // Returns a default, invalid handle, that is meant to indicate a missing - // Transport DIB. - static Handle DefaultHandleValue() { return NULL; } - - // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE - // ACTUALLY USED AS A REAL HANDLE. - static Handle GetFakeHandleForTest() { - static int fake_handle = 10; - return reinterpret_cast<Handle>(fake_handle++); - } -#elif defined(OS_MACOSX) - typedef base::SharedMemoryHandle Handle; - // On Mac, the inode number of the backing file is used as an id. - typedef base::SharedMemoryId Id; - - // Returns a default, invalid handle, that is meant to indicate a missing - // Transport DIB. - static Handle DefaultHandleValue() { return Handle(); } - - // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE - // ACTUALLY USED AS A REAL HANDLE. - static Handle GetFakeHandleForTest() { - static int fake_handle = 10; - return Handle(fake_handle++, false); - } -#elif defined(USE_X11) - typedef int Handle; // These two ints are SysV IPC shared memory keys - struct Id { - // Ensure that default initialized Ids are invalid. - Id() : shmkey(-1) { - } - - bool operator<(const Id& other) const { - return shmkey < other.shmkey; - } - - int shmkey; - }; - - // Returns a default, invalid handle, that is meant to indicate a missing - // Transport DIB. - static Handle DefaultHandleValue() { return -1; } - - // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE - // ACTUALLY USED AS A REAL HANDLE. - static Handle GetFakeHandleForTest() { - static int fake_handle = 10; - return fake_handle++; - } -#elif defined(OS_ANDROID) - typedef base::SharedMemoryHandle Handle; - typedef base::SharedMemoryHandle Id; - - // Returns a default, invalid handle, that is meant to indicate a missing - // Transport DIB. - static Handle DefaultHandleValue() { return Handle(); } - - // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE - // ACTUALLY USED AS A REAL HANDLE. - static Handle GetFakeHandleForTest() { - static int fake_handle = 10; - return Handle(fake_handle++, false); - } -#endif - - // Create a new TransportDIB, returning NULL on failure. - // - // The size is the minimum size in bytes of the memory backing the transport - // DIB (we may actually allocate more than that to give us better reuse when - // cached). - // - // The sequence number is used to uniquely identify the transport DIB. It - // should be unique for all transport DIBs ever created in the same - // renderer. - static TransportDIB* Create(size_t size, uint32 sequence_num); - - // Map the referenced transport DIB. The caller owns the returned object. - // Returns NULL on failure. - static TransportDIB* Map(Handle transport_dib); - - // Create a new |TransportDIB| with a handle to the shared memory. This - // always returns a valid pointer. The DIB is not mapped. - static TransportDIB* CreateWithHandle(Handle handle); - - // Returns true if the handle is valid. - static bool is_valid_handle(Handle dib); - - // Returns true if the ID refers to a valid dib. - static bool is_valid_id(Id id); - - // Returns a canvas using the memory of this TransportDIB. The returned - // pointer will be owned by the caller. The bitmap will be of the given size, - // which should fit inside this memory. - // - // On POSIX, this |TransportDIB| will be mapped if not already. On Windows, - // this |TransportDIB| will NOT be mapped and should not be mapped prior, - // because PlatformCanvas will map the file internally. - // - // Will return NULL on allocation failure. This could be because the image - // is too large to map into the current process' address space. - skia::PlatformCanvas* GetPlatformCanvas(int w, int h); - - // Map the DIB into the current process if it is not already. This is used to - // map a DIB that has already been created. Returns true if the DIB is mapped. - bool Map(); - - // Return a pointer to the shared memory. - void* memory() const; - - // Return the maximum size of the shared memory. This is not the amount of - // data which is valid, you have to know that via other means, this is simply - // the maximum amount that /could/ be valid. - size_t size() const { return size_; } - - // Return the identifier which can be used to refer to this shared memory - // on the wire. - Id id() const; - - // Return a handle to the underlying shared memory. This can be sent over the - // wire to give this transport DIB to another process. - Handle handle() const; - -#if defined(USE_X11) - // Map the shared memory into the X server and return an id for the shared - // segment. - XID MapToX(Display* connection); -#endif - - private: - TransportDIB(); -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_ANDROID) - explicit TransportDIB(base::SharedMemoryHandle dib); - base::SharedMemory shared_memory_; - uint32 sequence_num_; -#elif defined(USE_X11) - Id key_; // SysV shared memory id - void* address_; // mapped address - XSharedMemoryId x_shm_; // X id for the shared segment - Display* display_; // connection to the X server -#endif - size_t size_; // length, in bytes - - DISALLOW_COPY_AND_ASSIGN(TransportDIB); -}; - -#endif // UI_GFX_SURFACE_TRANSPORT_DIB_H_ diff --git a/ui/gfx/surface/transport_dib_android.cc b/ui/gfx/surface/transport_dib_android.cc deleted file mode 100644 index 432ae71..0000000 --- a/ui/gfx/surface/transport_dib_android.cc +++ /dev/null @@ -1,101 +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/transport_dib.h" - -#include <unistd.h> -#include <sys/stat.h> - -#include "base/eintr_wrapper.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/shared_memory.h" -#include "skia/ext/platform_canvas.h" - -TransportDIB::TransportDIB() - : size_(0) { -} - -TransportDIB::TransportDIB(TransportDIB::Handle dib) - : shared_memory_(dib, false /* read write */), - size_(0) { -} - -TransportDIB::~TransportDIB() { -} - -// static -TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { - TransportDIB* dib = new TransportDIB; - // We will use ashmem_get_size_region() to figure out the size in Map(size). - if (!dib->shared_memory_.CreateAndMapAnonymous(size)) { - delete dib; - return NULL; - } - - dib->size_ = size; - return dib; -} - -// static -TransportDIB* TransportDIB::Map(Handle handle) { - scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); - if (!dib->Map()) - return NULL; - return dib.release(); -} - -// static -TransportDIB* TransportDIB::CreateWithHandle(Handle handle) { - return new TransportDIB(handle); -} - -// static -bool TransportDIB::is_valid_handle(Handle dib) { - return dib.fd >= 0; -} - -// static -bool TransportDIB::is_valid_id(Id id) { - // Same as is_valid_handle(). - return id.fd >= 0; -} - -skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - if (!memory() && !Map()) - return NULL; - scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); - if (!canvas->initialize(w, h, true, reinterpret_cast<uint8_t*>(memory()))) { - // TODO(husky): Remove when http://b/issue?id=4233182 is definitely fixed. - LOG(ERROR) << "Failed to initialize canvas of size " << w << "x" << h; - return NULL; - } - return canvas.release(); -} - -bool TransportDIB::Map() { - if (!is_valid_handle(handle())) - return false; - // We will use ashmem_get_size_region() to figure out the size in Map(size). - if (!shared_memory_.Map(0)) - return false; - - // TODO: Note that using created_size() below is a hack. See the comment in - // SharedMemory::Map(). - size_ = shared_memory_.created_size(); - return true; -} - -void* TransportDIB::memory() const { - return shared_memory_.memory(); -} - -TransportDIB::Id TransportDIB::id() const { - // Use FileDescriptor as id. - return shared_memory_.handle(); -} - -TransportDIB::Handle TransportDIB::handle() const { - return shared_memory_.handle(); -} diff --git a/ui/gfx/surface/transport_dib_linux.cc b/ui/gfx/surface/transport_dib_linux.cc deleted file mode 100644 index c41ea9e..0000000 --- a/ui/gfx/surface/transport_dib_linux.cc +++ /dev/null @@ -1,141 +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/transport_dib.h" - -#include <errno.h> -#include <stdlib.h> -#include <sys/ipc.h> -#include <sys/shm.h> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "skia/ext/platform_canvas.h" -#include "ui/base/x/x11_util.h" -#include "ui/gfx/size.h" - -// The shmat system call uses this as it's invalid return address -static void *const kInvalidAddress = (void*) -1; - -TransportDIB::TransportDIB() - : address_(kInvalidAddress), - x_shm_(0), - display_(NULL), - size_(0) { -} - -TransportDIB::~TransportDIB() { - if (address_ != kInvalidAddress) { - shmdt(address_); - address_ = kInvalidAddress; - } - - if (x_shm_) { - DCHECK(display_); - ui::DetachSharedMemory(display_, x_shm_); - } -} - -// static -TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { - // We use a mode of 0666 since the X server won't attach to memory which is - // 0600 since it can't know if it (as a root process) is being asked to map - // someone else's private shared memory region. - const int shmkey = shmget(IPC_PRIVATE, size, 0666); - if (shmkey == -1) { - DLOG(ERROR) << "Failed to create SysV shared memory region" - << " errno:" << errno; - return NULL; - } - - void* address = shmat(shmkey, NULL /* desired address */, 0 /* flags */); - // Here we mark the shared memory for deletion. Since we attached it in the - // line above, it doesn't actually get deleted but, if we crash, this means - // that the kernel will automatically clean it up for us. - shmctl(shmkey, IPC_RMID, 0); - if (address == kInvalidAddress) - return NULL; - - TransportDIB* dib = new TransportDIB; - - dib->key_.shmkey = shmkey; - dib->address_ = address; - dib->size_ = size; - return dib; -} - -// static -TransportDIB* TransportDIB::Map(Handle handle) { - scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); - if (!dib->Map()) - return NULL; - return dib.release(); -} - -// static -TransportDIB* TransportDIB::CreateWithHandle(Handle shmkey) { - TransportDIB* dib = new TransportDIB; - dib->key_.shmkey = shmkey; - return dib; -} - -// static -bool TransportDIB::is_valid_handle(Handle dib) { - return dib >= 0; -} - -// static -bool TransportDIB::is_valid_id(Id id) { - return id.shmkey != -1; -} - -skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - if (address_ == kInvalidAddress && !Map()) - return NULL; - scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); - if (!canvas->initialize(w, h, true, reinterpret_cast<uint8_t*>(memory()))) - return NULL; - return canvas.release(); -} - -bool TransportDIB::Map() { - if (!is_valid_id(key_)) - return false; - if (address_ != kInvalidAddress) - return true; - - struct shmid_ds shmst; - if (shmctl(key_.shmkey, IPC_STAT, &shmst) == -1) - return false; - - void* address = shmat(key_.shmkey, NULL /* desired address */, 0 /* flags */); - if (address == kInvalidAddress) - return false; - - address_ = address; - size_ = shmst.shm_segsz; - return true; -} - -void* TransportDIB::memory() const { - DCHECK_NE(address_, kInvalidAddress); - return address_; -} - -TransportDIB::Id TransportDIB::id() const { - return key_; -} - -TransportDIB::Handle TransportDIB::handle() const { - return key_.shmkey; -} - -XID TransportDIB::MapToX(Display* display) { - if (!x_shm_) { - x_shm_ = ui::AttachSharedMemory(display, key_.shmkey); - display_ = display; - } - - return x_shm_; -} diff --git a/ui/gfx/surface/transport_dib_mac.cc b/ui/gfx/surface/transport_dib_mac.cc deleted file mode 100644 index 23c6f37..0000000 --- a/ui/gfx/surface/transport_dib_mac.cc +++ /dev/null @@ -1,98 +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/transport_dib.h" - -#include <unistd.h> -#include <sys/stat.h> - -#include "base/eintr_wrapper.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/shared_memory.h" -#include "skia/ext/platform_canvas.h" - -TransportDIB::TransportDIB() - : size_(0) { -} - -TransportDIB::TransportDIB(TransportDIB::Handle dib) - : shared_memory_(dib, false /* read write */), - size_(0) { -} - -TransportDIB::~TransportDIB() { -} - -// static -TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { - TransportDIB* dib = new TransportDIB; - if (!dib->shared_memory_.CreateAndMapAnonymous(size)) { - delete dib; - return NULL; - } - - dib->size_ = size; - return dib; -} - -// static -TransportDIB* TransportDIB::Map(Handle handle) { - scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); - if (!dib->Map()) - return NULL; - return dib.release(); -} - -// static -TransportDIB* TransportDIB::CreateWithHandle(Handle handle) { - return new TransportDIB(handle); -} - -// static -bool TransportDIB::is_valid_handle(Handle dib) { - return dib.fd >= 0; -} - -// static -bool TransportDIB::is_valid_id(Id id) { - return id != 0; -} - -skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - if (!memory() && !Map()) - return NULL; - scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); - if (!canvas->initialize(w, h, true, reinterpret_cast<uint8_t*>(memory()))) - return NULL; - return canvas.release(); -} - -bool TransportDIB::Map() { - if (!is_valid_handle(handle())) - return false; - if (memory()) - return true; - - struct stat st; - if ((fstat(shared_memory_.handle().fd, &st) != 0) || - (!shared_memory_.Map(st.st_size))) { - return false; - } - - size_ = st.st_size; - return true; -} - -void* TransportDIB::memory() const { - return shared_memory_.memory(); -} - -TransportDIB::Id TransportDIB::id() const { - return shared_memory_.id(); -} - -TransportDIB::Handle TransportDIB::handle() const { - return shared_memory_.handle(); -} diff --git a/ui/gfx/surface/transport_dib_win.cc b/ui/gfx/surface/transport_dib_win.cc deleted file mode 100644 index a7df666..0000000 --- a/ui/gfx/surface/transport_dib_win.cc +++ /dev/null @@ -1,110 +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/transport_dib.h" - -#include <windows.h> - -#include <limits> - -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/sys_info.h" -#include "skia/ext/platform_canvas.h" - -TransportDIB::TransportDIB() { -} - -TransportDIB::~TransportDIB() { -} - -TransportDIB::TransportDIB(HANDLE handle) - : shared_memory_(handle, false /* read write */) { -} - -// static -TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { - size_t allocation_granularity = base::SysInfo::VMAllocationGranularity(); - size = size / allocation_granularity + 1; - size = size * allocation_granularity; - - TransportDIB* dib = new TransportDIB; - - if (!dib->shared_memory_.CreateAnonymous(size)) { - delete dib; - return NULL; - } - - dib->size_ = size; - dib->sequence_num_ = sequence_num; - - return dib; -} - -// static -TransportDIB* TransportDIB::Map(Handle handle) { - scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); - if (!dib->Map()) - return NULL; - return dib.release(); -} - -// static -TransportDIB* TransportDIB::CreateWithHandle(Handle handle) { - return new TransportDIB(handle); -} - -// static -bool TransportDIB::is_valid_handle(Handle dib) { - return dib != NULL; -} - -// static -bool TransportDIB::is_valid_id(TransportDIB::Id id) { - return is_valid_handle(id.handle); -} - -skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - // This DIB already mapped the file into this process, but PlatformCanvas - // will map it again. - DCHECK(!memory()) << "Mapped file twice in the same process."; - - scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); - if (!canvas->initialize(w, h, true, handle())) - return NULL; - return canvas.release(); -} - -bool TransportDIB::Map() { - if (!is_valid_handle(handle())) - return false; - if (memory()) - return true; - - if (!shared_memory_.Map(0 /* map whole shared memory segment */)) { - LOG(ERROR) << "Failed to map transport DIB" - << " handle:" << shared_memory_.handle() - << " error:" << ::GetLastError(); - return false; - } - - // There doesn't seem to be any way to find the size of the shared memory - // region! GetFileSize indicates that the handle is invalid. Thus, we - // conservatively set the size to the maximum and hope that the renderer - // isn't about to ask us to read off the end of the array. - size_ = std::numeric_limits<size_t>::max(); - return true; -} - -void* TransportDIB::memory() const { - return shared_memory_.memory(); -} - -TransportDIB::Handle TransportDIB::handle() const { - return shared_memory_.handle(); -} - -TransportDIB::Id TransportDIB::id() const { - return Id(handle(), sequence_num_); -} |