1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/common/gpu/image_transport_surface_iosurface_mac.h"
7 #include "content/common/gpu/gpu_messages.h"
8 #include "content/common/gpu/surface_handle_types_mac.h"
13 // IOSurface dimensions will be rounded up to a multiple of this value in order
14 // to reduce memory thrashing during resize. This must be a power of 2.
15 const uint32 kIOSurfaceDimensionRoundup = 64;
17 int RoundUpSurfaceDimension(int number) {
19 // Cast into unsigned space for portable bitwise ops.
20 uint32 unsigned_number = static_cast<uint32>(number);
21 uint32 roundup_sub_1 = kIOSurfaceDimensionRoundup - 1;
22 unsigned_number = (unsigned_number + roundup_sub_1) & ~roundup_sub_1;
23 return static_cast<int>(unsigned_number);
26 void AddBooleanValue(CFMutableDictionaryRef dictionary,
27 const CFStringRef key,
29 CFDictionaryAddValue(dictionary, key,
30 (value ? kCFBooleanTrue : kCFBooleanFalse));
33 void AddIntegerValue(CFMutableDictionaryRef dictionary,
34 const CFStringRef key,
36 base::ScopedCFTypeRef<CFNumberRef> number(
37 CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
38 CFDictionaryAddValue(dictionary, key, number.get());
43 IOSurfaceStorageProvider::IOSurfaceStorageProvider(
44 ImageTransportSurfaceFBO* transport_surface)
45 : transport_surface_(transport_surface) {}
47 IOSurfaceStorageProvider::~IOSurfaceStorageProvider() {
51 gfx::Size IOSurfaceStorageProvider::GetRoundedSize(gfx::Size size) {
52 return gfx::Size(RoundUpSurfaceDimension(size.width()),
53 RoundUpSurfaceDimension(size.height()));
56 bool IOSurfaceStorageProvider::AllocateColorBufferStorage(
57 CGLContextObj context, GLuint texture,
58 gfx::Size pixel_size, float scale_factor) {
59 // Allocate a new IOSurface, which is the GPU resource that can be
60 // shared across processes.
61 base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
62 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault,
64 &kCFTypeDictionaryKeyCallBacks,
65 &kCFTypeDictionaryValueCallBacks));
66 AddIntegerValue(properties,
69 AddIntegerValue(properties,
72 AddIntegerValue(properties,
73 kIOSurfaceBytesPerElement, 4);
74 AddBooleanValue(properties,
75 kIOSurfaceIsGlobal, true);
76 // I believe we should be able to unreference the IOSurfaces without
77 // synchronizing with the browser process because they are
78 // ultimately reference counted by the operating system.
79 io_surface_.reset(IOSurfaceCreate(properties));
80 io_surface_id_ = IOSurfaceGetID(io_surface_);
82 // Don't think we need to identify a plane.
84 CGLError cglerror = CGLTexImageIOSurface2D(
86 GL_TEXTURE_RECTANGLE_ARB,
91 GL_UNSIGNED_INT_8_8_8_8_REV,
94 if (cglerror != kCGLNoError) {
95 DLOG(ERROR) << "CGLTexImageIOSurface2D failed with CGL error: " << cglerror;
103 void IOSurfaceStorageProvider::FreeColorBufferStorage() {
108 void IOSurfaceStorageProvider::SwapBuffers(
109 const gfx::Size& size, float scale_factor) {
110 // The browser compositor will throttle itself, so we are free to unblock the
111 // context immediately. Make sure that the browser is doing its throttling
112 // appropriately by ensuring that the previous swap was acknowledged before
113 // we get another swap.
114 DCHECK(pending_swapped_surfaces_.empty());
115 pending_swapped_surfaces_.push_back(io_surface_);
117 transport_surface_->SendSwapBuffers(
118 SurfaceHandleFromIOSurfaceID(io_surface_id_), size, scale_factor);
121 void IOSurfaceStorageProvider::WillWriteToBackbuffer() {
124 void IOSurfaceStorageProvider::DiscardBackbuffer() {
127 void IOSurfaceStorageProvider::SwapBuffersAckedByBrowser() {
128 DCHECK(!pending_swapped_surfaces_.empty());
129 pending_swapped_surfaces_.pop_front();
132 } // namespace content