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 "ui/accelerated_widget_mac/surface_handle_types.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
),
46 frame_scale_factor_(1) {}
48 IOSurfaceStorageProvider::~IOSurfaceStorageProvider() {
52 gfx::Size
IOSurfaceStorageProvider::GetRoundedSize(gfx::Size size
) {
53 return gfx::Size(RoundUpSurfaceDimension(size
.width()),
54 RoundUpSurfaceDimension(size
.height()));
57 bool IOSurfaceStorageProvider::AllocateColorBufferStorage(
58 CGLContextObj context
, const base::Closure
& context_dirtied_callback
,
59 GLuint texture
, gfx::Size pixel_size
, float scale_factor
) {
60 // Allocate a new IOSurface, which is the GPU resource that can be
61 // shared across processes.
62 base::ScopedCFTypeRef
<CFMutableDictionaryRef
> properties
;
63 properties
.reset(CFDictionaryCreateMutable(kCFAllocatorDefault
,
65 &kCFTypeDictionaryKeyCallBacks
,
66 &kCFTypeDictionaryValueCallBacks
));
67 AddIntegerValue(properties
,
70 AddIntegerValue(properties
,
73 AddIntegerValue(properties
,
74 kIOSurfaceBytesPerElement
, 4);
75 AddBooleanValue(properties
,
76 kIOSurfaceIsGlobal
, true);
77 // I believe we should be able to unreference the IOSurfaces without
78 // synchronizing with the browser process because they are
79 // ultimately reference counted by the operating system.
80 io_surface_
.reset(IOSurfaceCreate(properties
));
81 io_surface_id_
= IOSurfaceGetID(io_surface_
);
83 // Don't think we need to identify a plane.
85 CGLError cglerror
= CGLTexImageIOSurface2D(
87 GL_TEXTURE_RECTANGLE_ARB
,
92 GL_UNSIGNED_INT_8_8_8_8_REV
,
95 if (cglerror
!= kCGLNoError
) {
96 DLOG(ERROR
) << "CGLTexImageIOSurface2D failed with CGL error: " << cglerror
;
104 void IOSurfaceStorageProvider::FreeColorBufferStorage() {
109 void IOSurfaceStorageProvider::FrameSizeChanged(const gfx::Size
& pixel_size
,
110 float scale_factor
) {
111 frame_pixel_size_
= pixel_size
;
112 frame_scale_factor_
= scale_factor
;
115 void IOSurfaceStorageProvider::SwapBuffers(const gfx::Rect
& dirty_rect
) {
116 // The browser compositor will throttle itself, so we are free to unblock the
117 // context immediately. Make sure that the browser is doing its throttling
118 // appropriately by ensuring that the previous swap was acknowledged before
119 // we get another swap.
120 DCHECK(pending_swapped_surfaces_
.empty());
121 pending_swapped_surfaces_
.push_back(io_surface_
);
123 transport_surface_
->SendSwapBuffers(
124 ui::SurfaceHandleFromIOSurfaceID(io_surface_id_
),
126 frame_scale_factor_
);
129 void IOSurfaceStorageProvider::WillWriteToBackbuffer() {
132 void IOSurfaceStorageProvider::DiscardBackbuffer() {
135 void IOSurfaceStorageProvider::SwapBuffersAckedByBrowser(
136 bool disable_throttling
) {
137 DCHECK(!pending_swapped_surfaces_
.empty());
138 pending_swapped_surfaces_
.pop_front();
141 } // namespace content