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

Side by Side Diff: content/common/gpu/image_transport_surface_mac.cc

Issue 337303003: CARemoteLayer alive-ish (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 6 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 unified diff | Download patch
« no previous file with comments | « content/common/gpu/image_transport_surface_mac.h ('k') | content/common/view_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/image_transport_surface.h" 5 #include "content/common/gpu/image_transport_surface_mac.h"
6 6
7 #include "base/mac/scoped_cftyperef.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "content/common/gpu/gpu_command_buffer_stub.h"
10 #include "content/common/gpu/gpu_messages.h" 7 #include "content/common/gpu/gpu_messages.h"
8 #include "content/common/gpu/image_transport_surface_iosurface_mac.h"
11 #include "ui/gfx/native_widget_types.h" 9 #include "ui/gfx/native_widget_types.h"
12 #include "ui/gl/gl_bindings.h"
13 #include "ui/gl/gl_context.h" 10 #include "ui/gl/gl_context.h"
14 #include "ui/gl/gl_implementation.h" 11 #include "ui/gl/gl_implementation.h"
15 #include "ui/gl/gl_surface_cgl.h" 12 #include "ui/gl/gl_surface_cgl.h"
16 #include "ui/gl/gl_surface_osmesa.h" 13 #include "ui/gl/gl_surface_osmesa.h"
17 14
18 // Note that this must be included after gl_bindings.h to avoid conflicts. 15 namespace content {
19 #include <OpenGL/CGLIOSurface.h>
20 16
21 namespace content { 17 ImageTransportSurfaceFBO::ImageTransportSurfaceFBO(
22 namespace { 18 StorageProvider* storage_provider,
23
24 // IOSurface dimensions will be rounded up to a multiple of this value in order
25 // to reduce memory thrashing during resize. This must be a power of 2.
26 const uint32 kIOSurfaceDimensionRoundup = 64;
27
28 int RoundUpSurfaceDimension(int number) {
29 DCHECK(number >= 0);
30 // Cast into unsigned space for portable bitwise ops.
31 uint32 unsigned_number = static_cast<uint32>(number);
32 uint32 roundup_sub_1 = kIOSurfaceDimensionRoundup - 1;
33 unsigned_number = (unsigned_number + roundup_sub_1) & ~roundup_sub_1;
34 return static_cast<int>(unsigned_number);
35 }
36
37 // We are backed by an offscreen surface for the purposes of creating
38 // a context, but use FBOs to render to texture backed IOSurface
39 class IOSurfaceImageTransportSurface
40 : public gfx::NoOpGLSurfaceCGL,
41 public ImageTransportSurface,
42 public GpuCommandBufferStub::DestructionObserver {
43 public:
44 IOSurfaceImageTransportSurface(GpuChannelManager* manager,
45 GpuCommandBufferStub* stub,
46 gfx::PluginWindowHandle handle);
47
48 // GLSurface implementation
49 virtual bool Initialize() OVERRIDE;
50 virtual void Destroy() OVERRIDE;
51 virtual bool DeferDraws() OVERRIDE;
52 virtual bool IsOffscreen() OVERRIDE;
53 virtual bool SwapBuffers() OVERRIDE;
54 virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE;
55 virtual bool SupportsPostSubBuffer() OVERRIDE;
56 virtual gfx::Size GetSize() OVERRIDE;
57 virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
58 virtual unsigned int GetBackingFrameBufferObject() OVERRIDE;
59 virtual bool SetBackbufferAllocation(bool allocated) OVERRIDE;
60 virtual void SetFrontbufferAllocation(bool allocated) OVERRIDE;
61
62 protected:
63 // ImageTransportSurface implementation
64 virtual void OnBufferPresented(
65 const AcceleratedSurfaceMsg_BufferPresented_Params& params) OVERRIDE;
66 virtual void OnResize(gfx::Size size, float scale_factor) OVERRIDE;
67 virtual void SetLatencyInfo(
68 const std::vector<ui::LatencyInfo>&) OVERRIDE;
69 virtual void WakeUpGpu() OVERRIDE;
70
71 // GpuCommandBufferStub::DestructionObserver implementation.
72 virtual void OnWillDestroyStub() OVERRIDE;
73
74 private:
75 virtual ~IOSurfaceImageTransportSurface() OVERRIDE;
76
77 void AdjustBufferAllocation();
78 void UnrefIOSurface();
79 void CreateIOSurface();
80
81 // Tracks the current buffer allocation state.
82 bool backbuffer_suggested_allocation_;
83 bool frontbuffer_suggested_allocation_;
84
85 uint32 fbo_id_;
86 GLuint texture_id_;
87 GLuint depth_stencil_renderbuffer_id_;
88
89 base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
90
91 // The id of |io_surface_| or 0 if that's NULL.
92 uint64 io_surface_handle_;
93
94 // Weak pointer to the context that this was last made current to.
95 gfx::GLContext* context_;
96
97 gfx::Size size_;
98 gfx::Size rounded_size_;
99 float scale_factor_;
100
101 // Whether or not we've successfully made the surface current once.
102 bool made_current_;
103
104 // Whether a SwapBuffers is pending.
105 bool is_swap_buffers_pending_;
106
107 // Whether we unscheduled command buffer because of pending SwapBuffers.
108 bool did_unschedule_;
109
110 std::vector<ui::LatencyInfo> latency_info_;
111
112 scoped_ptr<ImageTransportHelper> helper_;
113
114 DISALLOW_COPY_AND_ASSIGN(IOSurfaceImageTransportSurface);
115 };
116
117 void AddBooleanValue(CFMutableDictionaryRef dictionary,
118 const CFStringRef key,
119 bool value) {
120 CFDictionaryAddValue(dictionary, key,
121 (value ? kCFBooleanTrue : kCFBooleanFalse));
122 }
123
124 void AddIntegerValue(CFMutableDictionaryRef dictionary,
125 const CFStringRef key,
126 int32 value) {
127 base::ScopedCFTypeRef<CFNumberRef> number(
128 CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
129 CFDictionaryAddValue(dictionary, key, number.get());
130 }
131
132 IOSurfaceImageTransportSurface::IOSurfaceImageTransportSurface(
133 GpuChannelManager* manager, 19 GpuChannelManager* manager,
134 GpuCommandBufferStub* stub, 20 GpuCommandBufferStub* stub,
135 gfx::PluginWindowHandle handle) 21 gfx::PluginWindowHandle handle)
136 : gfx::NoOpGLSurfaceCGL(gfx::Size(1, 1)), 22 : storage_provider_(storage_provider),
137 backbuffer_suggested_allocation_(true), 23 backbuffer_suggested_allocation_(true),
138 frontbuffer_suggested_allocation_(true), 24 frontbuffer_suggested_allocation_(true),
139 fbo_id_(0), 25 fbo_id_(0),
140 texture_id_(0), 26 texture_id_(0),
141 depth_stencil_renderbuffer_id_(0), 27 depth_stencil_renderbuffer_id_(0),
142 io_surface_handle_(0), 28 has_complete_framebuffer_(false),
143 context_(NULL), 29 context_(NULL),
144 scale_factor_(1.f), 30 scale_factor_(1.f),
145 made_current_(false), 31 made_current_(false),
146 is_swap_buffers_pending_(false), 32 is_swap_buffers_pending_(false),
147 did_unschedule_(false) { 33 did_unschedule_(false) {
148 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); 34 helper_.reset(new ImageTransportHelper(this, manager, stub, handle));
149 } 35 }
150 36
151 IOSurfaceImageTransportSurface::~IOSurfaceImageTransportSurface() { 37 ImageTransportSurfaceFBO::~ImageTransportSurfaceFBO() {
152 } 38 }
153 39
154 bool IOSurfaceImageTransportSurface::Initialize() { 40 bool ImageTransportSurfaceFBO::Initialize() {
155 // Only support IOSurfaces if the GL implementation is the native desktop GL. 41 // Only support IOSurfaces if the GL implementation is the native desktop GL.
156 // IO surfaces will not work with, for example, OSMesa software renderer 42 // IO surfaces will not work with, for example, OSMesa software renderer
157 // GL contexts. 43 // GL contexts.
158 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL && 44 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL &&
159 gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL) 45 gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL)
160 return false; 46 return false;
161 47
162 if (!helper_->Initialize()) 48 if (!helper_->Initialize())
163 return false; 49 return false;
164 50
165 if (!NoOpGLSurfaceCGL::Initialize()) {
166 helper_->Destroy();
167 return false;
168 }
169
170 helper_->stub()->AddDestructionObserver(this); 51 helper_->stub()->AddDestructionObserver(this);
171 return true; 52 return true;
172 } 53 }
173 54
174 void IOSurfaceImageTransportSurface::Destroy() { 55 void ImageTransportSurfaceFBO::Destroy() {
175 UnrefIOSurface(); 56 DestroyFramebuffer();
176 57
177 helper_->Destroy(); 58 helper_->Destroy();
178 NoOpGLSurfaceCGL::Destroy();
179 } 59 }
180 60
181 bool IOSurfaceImageTransportSurface::DeferDraws() { 61 bool ImageTransportSurfaceFBO::DeferDraws() {
182 // The command buffer hit a draw/clear command that could clobber the 62 // The command buffer hit a draw/clear command that could clobber the
183 // IOSurface in use by an earlier SwapBuffers. If a Swap is pending, abort 63 // IOSurface in use by an earlier SwapBuffers. If a Swap is pending, abort
184 // processing of the command by returning true and unschedule until the Swap 64 // processing of the command by returning true and unschedule until the Swap
185 // Ack arrives. 65 // Ack arrives.
186 if(did_unschedule_) 66 if(did_unschedule_)
187 return true; // Still unscheduled, so just return true. 67 return true; // Still unscheduled, so just return true.
188 if (is_swap_buffers_pending_) { 68 if (is_swap_buffers_pending_) {
189 did_unschedule_ = true; 69 did_unschedule_ = true;
190 helper_->SetScheduled(false); 70 helper_->SetScheduled(false);
191 return true; 71 return true;
192 } 72 }
193 return false; 73 return false;
194 } 74 }
195 75
196 bool IOSurfaceImageTransportSurface::IsOffscreen() { 76 bool ImageTransportSurfaceFBO::IsOffscreen() {
197 return false; 77 return false;
198 } 78 }
199 79
200 bool IOSurfaceImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) { 80 bool ImageTransportSurfaceFBO::OnMakeCurrent(gfx::GLContext* context) {
201 context_ = context; 81 context_ = context;
202 82
203 if (made_current_) 83 if (made_current_)
204 return true; 84 return true;
205 85
206 OnResize(gfx::Size(1, 1), 1.f); 86 OnResize(gfx::Size(1, 1), 1.f);
207 87
208 made_current_ = true; 88 made_current_ = true;
209 return true; 89 return true;
210 } 90 }
211 91
212 unsigned int IOSurfaceImageTransportSurface::GetBackingFrameBufferObject() { 92 unsigned int ImageTransportSurfaceFBO::GetBackingFrameBufferObject() {
213 return fbo_id_; 93 return fbo_id_;
214 } 94 }
215 95
216 bool IOSurfaceImageTransportSurface::SetBackbufferAllocation(bool allocation) { 96 bool ImageTransportSurfaceFBO::SetBackbufferAllocation(bool allocation) {
217 if (backbuffer_suggested_allocation_ == allocation) 97 if (backbuffer_suggested_allocation_ == allocation)
218 return true; 98 return true;
219 backbuffer_suggested_allocation_ = allocation; 99 backbuffer_suggested_allocation_ = allocation;
220 AdjustBufferAllocation(); 100 AdjustBufferAllocation();
221 return true; 101 return true;
222 } 102 }
223 103
224 void IOSurfaceImageTransportSurface::SetFrontbufferAllocation(bool allocation) { 104 void ImageTransportSurfaceFBO::SetFrontbufferAllocation(bool allocation) {
225 if (frontbuffer_suggested_allocation_ == allocation) 105 if (frontbuffer_suggested_allocation_ == allocation)
226 return; 106 return;
227 frontbuffer_suggested_allocation_ = allocation; 107 frontbuffer_suggested_allocation_ = allocation;
228 AdjustBufferAllocation(); 108 AdjustBufferAllocation();
229 } 109 }
230 110
231 void IOSurfaceImageTransportSurface::AdjustBufferAllocation() { 111 void ImageTransportSurfaceFBO::AdjustBufferAllocation() {
232 // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is 112 // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is
233 // free'd when both the browser and gpu processes have Unref'd the IOSurface. 113 // free'd when both the browser and gpu processes have Unref'd the IOSurface.
234 if (!backbuffer_suggested_allocation_ && 114 if (!backbuffer_suggested_allocation_ &&
235 !frontbuffer_suggested_allocation_ && 115 !frontbuffer_suggested_allocation_ &&
236 io_surface_.get()) { 116 has_complete_framebuffer_) {
237 UnrefIOSurface(); 117 DestroyFramebuffer();
238 helper_->Suspend(); 118 helper_->Suspend();
239 } else if (backbuffer_suggested_allocation_ && !io_surface_) { 119 } else if (backbuffer_suggested_allocation_ && !has_complete_framebuffer_) {
240 CreateIOSurface(); 120 CreateFramebuffer();
241 } 121 }
242 } 122 }
243 123
244 bool IOSurfaceImageTransportSurface::SwapBuffers() { 124 bool ImageTransportSurfaceFBO::SwapBuffers() {
245 DCHECK(backbuffer_suggested_allocation_); 125 DCHECK(backbuffer_suggested_allocation_);
246 if (!frontbuffer_suggested_allocation_) 126 if (!frontbuffer_suggested_allocation_)
247 return true; 127 return true;
248 glFlush(); 128 glFlush();
249 129
250 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; 130 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
251 params.surface_handle = io_surface_handle_; 131 storage_provider_->PopulateSwapBuffersStorageParams(&params);
252 params.size = GetSize(); 132 params.size = GetSize();
253 params.scale_factor = scale_factor_; 133 params.scale_factor = scale_factor_;
254 params.latency_info.swap(latency_info_); 134 params.latency_info.swap(latency_info_);
255 helper_->SendAcceleratedSurfaceBuffersSwapped(params); 135 helper_->SendAcceleratedSurfaceBuffersSwapped(params);
256 136
257 DCHECK(!is_swap_buffers_pending_); 137 DCHECK(!is_swap_buffers_pending_);
258 is_swap_buffers_pending_ = true; 138 is_swap_buffers_pending_ = true;
259 return true; 139 return true;
260 } 140 }
261 141
262 bool IOSurfaceImageTransportSurface::PostSubBuffer( 142 bool ImageTransportSurfaceFBO::PostSubBuffer(
263 int x, int y, int width, int height) { 143 int x, int y, int width, int height) {
264 DCHECK(backbuffer_suggested_allocation_); 144 DCHECK(backbuffer_suggested_allocation_);
265 if (!frontbuffer_suggested_allocation_) 145 if (!frontbuffer_suggested_allocation_)
266 return true; 146 return true;
267 glFlush(); 147 glFlush();
268 148
269 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; 149 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params;
270 params.surface_handle = io_surface_handle_; 150 storage_provider_->PopulateSubBufferStorageParams(&params);
271 params.x = x; 151 params.x = x;
272 params.y = y; 152 params.y = y;
273 params.width = width; 153 params.width = width;
274 params.height = height; 154 params.height = height;
275 params.surface_size = GetSize(); 155 params.surface_size = GetSize();
276 params.surface_scale_factor = scale_factor_; 156 params.surface_scale_factor = scale_factor_;
277 params.latency_info.swap(latency_info_); 157 params.latency_info.swap(latency_info_);
278 helper_->SendAcceleratedSurfacePostSubBuffer(params); 158 helper_->SendAcceleratedSurfacePostSubBuffer(params);
279 159
280 DCHECK(!is_swap_buffers_pending_); 160 DCHECK(!is_swap_buffers_pending_);
281 is_swap_buffers_pending_ = true; 161 is_swap_buffers_pending_ = true;
282 return true; 162 return true;
283 } 163 }
284 164
285 bool IOSurfaceImageTransportSurface::SupportsPostSubBuffer() { 165 bool ImageTransportSurfaceFBO::SupportsPostSubBuffer() {
286 return true; 166 return true;
287 } 167 }
288 168
289 gfx::Size IOSurfaceImageTransportSurface::GetSize() { 169 gfx::Size ImageTransportSurfaceFBO::GetSize() {
290 return size_; 170 return size_;
291 } 171 }
292 172
293 void IOSurfaceImageTransportSurface::OnBufferPresented( 173 void* ImageTransportSurfaceFBO::GetHandle() {
174 return NULL;
175 }
176
177 void ImageTransportSurfaceFBO::OnBufferPresented(
294 const AcceleratedSurfaceMsg_BufferPresented_Params& params) { 178 const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
295 DCHECK(is_swap_buffers_pending_); 179 DCHECK(is_swap_buffers_pending_);
296 180
297 context_->share_group()->SetRendererID(params.renderer_id); 181 context_->share_group()->SetRendererID(params.renderer_id);
298 is_swap_buffers_pending_ = false; 182 is_swap_buffers_pending_ = false;
299 if (did_unschedule_) { 183 if (did_unschedule_) {
300 did_unschedule_ = false; 184 did_unschedule_ = false;
301 helper_->SetScheduled(true); 185 helper_->SetScheduled(true);
302 } 186 }
303 } 187 }
304 188
305 void IOSurfaceImageTransportSurface::OnResize(gfx::Size size, 189 void ImageTransportSurfaceFBO::OnResize(gfx::Size size,
306 float scale_factor) { 190 float scale_factor) {
307 // This trace event is used in gpu_feature_browsertest.cc - the test will need 191 // This trace event is used in gpu_feature_browsertest.cc - the test will need
308 // to be updated if this event is changed or moved. 192 // to be updated if this event is changed or moved.
309 TRACE_EVENT2("gpu", "IOSurfaceImageTransportSurface::OnResize", 193 TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::OnResize",
310 "old_width", size_.width(), "new_width", size.width()); 194 "old_width", size_.width(), "new_width", size.width());
311 // Caching |context_| from OnMakeCurrent. It should still be current. 195 // Caching |context_| from OnMakeCurrent. It should still be current.
312 DCHECK(context_->IsCurrent(this)); 196 DCHECK(context_->IsCurrent(this));
313 197
314 size_ = size; 198 size_ = size;
315 scale_factor_ = scale_factor; 199 scale_factor_ = scale_factor;
316 200
317 CreateIOSurface(); 201 CreateFramebuffer();
318 } 202 }
319 203
320 void IOSurfaceImageTransportSurface::SetLatencyInfo( 204 void ImageTransportSurfaceFBO::SetLatencyInfo(
321 const std::vector<ui::LatencyInfo>& latency_info) { 205 const std::vector<ui::LatencyInfo>& latency_info) {
322 for (size_t i = 0; i < latency_info.size(); i++) 206 for (size_t i = 0; i < latency_info.size(); i++)
323 latency_info_.push_back(latency_info[i]); 207 latency_info_.push_back(latency_info[i]);
324 } 208 }
325 209
326 void IOSurfaceImageTransportSurface::WakeUpGpu() { 210 void ImageTransportSurfaceFBO::WakeUpGpu() {
327 NOTIMPLEMENTED(); 211 NOTIMPLEMENTED();
328 } 212 }
329 213
330 void IOSurfaceImageTransportSurface::OnWillDestroyStub() { 214 void ImageTransportSurfaceFBO::OnWillDestroyStub() {
331 helper_->stub()->RemoveDestructionObserver(this); 215 helper_->stub()->RemoveDestructionObserver(this);
332 Destroy(); 216 Destroy();
333 } 217 }
334 218
335 void IOSurfaceImageTransportSurface::UnrefIOSurface() { 219 void ImageTransportSurfaceFBO::DestroyFramebuffer() {
336 // If we have resources to destroy, then make sure that we have a current 220 // If we have resources to destroy, then make sure that we have a current
337 // context which we can use to delete the resources. 221 // context which we can use to delete the resources.
338 if (context_ || fbo_id_ || texture_id_ || depth_stencil_renderbuffer_id_) { 222 if (context_ || fbo_id_ || texture_id_ || depth_stencil_renderbuffer_id_) {
339 DCHECK(gfx::GLContext::GetCurrent() == context_); 223 DCHECK(gfx::GLContext::GetCurrent() == context_);
340 DCHECK(context_->IsCurrent(this)); 224 DCHECK(context_->IsCurrent(this));
341 DCHECK(CGLGetCurrentContext()); 225 DCHECK(CGLGetCurrentContext());
342 } 226 }
343 227
344 if (fbo_id_) { 228 if (fbo_id_) {
345 glDeleteFramebuffersEXT(1, &fbo_id_); 229 glDeleteFramebuffersEXT(1, &fbo_id_);
346 fbo_id_ = 0; 230 fbo_id_ = 0;
347 } 231 }
348 232
349 if (texture_id_) { 233 if (texture_id_) {
350 glDeleteTextures(1, &texture_id_); 234 glDeleteTextures(1, &texture_id_);
351 texture_id_ = 0; 235 texture_id_ = 0;
352 } 236 }
353 237
354 if (depth_stencil_renderbuffer_id_) { 238 if (depth_stencil_renderbuffer_id_) {
355 glDeleteRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_); 239 glDeleteRenderbuffersEXT(1, &depth_stencil_renderbuffer_id_);
356 depth_stencil_renderbuffer_id_ = 0; 240 depth_stencil_renderbuffer_id_ = 0;
357 } 241 }
358 242
359 io_surface_.reset(); 243 storage_provider_->FreeColorBufferStorage();
360 io_surface_handle_ = 0; 244
245 has_complete_framebuffer_ = false;
361 } 246 }
362 247
363 void IOSurfaceImageTransportSurface::CreateIOSurface() { 248 void ImageTransportSurfaceFBO::CreateFramebuffer() {
364 gfx::Size new_rounded_size(RoundUpSurfaceDimension(size_.width()), 249 gfx::Size new_rounded_size = storage_provider_->GetRoundedSize(size_);
365 RoundUpSurfaceDimension(size_.height()));
366 250
367 // Only recreate surface when the rounded up size has changed. 251 // Only recreate surface when the rounded up size has changed.
368 if (io_surface_.get() && new_rounded_size == rounded_size_) 252 if (has_complete_framebuffer_ && new_rounded_size == rounded_size_)
369 return; 253 return;
370 254
371 // This trace event is used in gpu_feature_browsertest.cc - the test will need 255 // This trace event is used in gpu_feature_browsertest.cc - the test will need
372 // to be updated if this event is changed or moved. 256 // to be updated if this event is changed or moved.
373 TRACE_EVENT2("gpu", "IOSurfaceImageTransportSurface::CreateIOSurface", 257 TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::CreateFramebuffer",
374 "width", new_rounded_size.width(), 258 "width", new_rounded_size.width(),
375 "height", new_rounded_size.height()); 259 "height", new_rounded_size.height());
376 260
377 rounded_size_ = new_rounded_size; 261 rounded_size_ = new_rounded_size;
378 262
263 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
264 // Mac OS X and is required for IOSurface interoperability.
265 GLenum target = GL_TEXTURE_RECTANGLE_ARB;
379 GLint previous_texture_id = 0; 266 GLint previous_texture_id = 0;
380 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); 267 glGetIntegerv(GL_TEXTURE_RECTANGLE_ARB, &previous_texture_id);
381 268
382 // Free the old IO Surface first to reduce memory fragmentation. 269 // Free the old IO Surface first to reduce memory fragmentation.
383 UnrefIOSurface(); 270 DestroyFramebuffer();
384 271
385 glGenFramebuffersEXT(1, &fbo_id_); 272 glGenFramebuffersEXT(1, &fbo_id_);
386 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); 273 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_);
387 274
388 glGenTextures(1, &texture_id_); 275 glGenTextures(1, &texture_id_);
389 276
390 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
391 // Mac OS X and is required for IOSurface interoperability.
392 GLenum target = GL_TEXTURE_RECTANGLE_ARB;
393 glBindTexture(target, texture_id_); 277 glBindTexture(target, texture_id_);
394 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 278 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
395 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 279 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
396 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 280 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
397 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 281 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
398 282
399 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 283 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
400 GL_COLOR_ATTACHMENT0_EXT, 284 GL_COLOR_ATTACHMENT0_EXT,
401 target, 285 target,
402 texture_id_, 286 texture_id_,
403 0); 287 0);
404 288
405
406 // Search through the provided attributes; if the caller has 289 // Search through the provided attributes; if the caller has
407 // requested a stencil buffer, try to get one. 290 // requested a stencil buffer, try to get one.
408 291
409 int32 stencil_bits = 292 int32 stencil_bits =
410 helper_->stub()->GetRequestedAttribute(EGL_STENCIL_SIZE); 293 helper_->stub()->GetRequestedAttribute(EGL_STENCIL_SIZE);
411 if (stencil_bits > 0) { 294 if (stencil_bits > 0) {
412 // Create and bind the stencil buffer 295 // Create and bind the stencil buffer
413 bool has_packed_depth_stencil = 296 bool has_packed_depth_stencil =
414 GLSurface::ExtensionsContain( 297 GLSurface::ExtensionsContain(
415 reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)), 298 reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
(...skipping 10 matching lines...) Expand all
426 GL_RENDERBUFFER_EXT, 309 GL_RENDERBUFFER_EXT,
427 depth_stencil_renderbuffer_id_); 310 depth_stencil_renderbuffer_id_);
428 } 311 }
429 312
430 // If we asked for stencil but the extension isn't present, 313 // If we asked for stencil but the extension isn't present,
431 // it's OK to silently fail; subsequent code will/must check 314 // it's OK to silently fail; subsequent code will/must check
432 // for the presence of a stencil buffer before attempting to 315 // for the presence of a stencil buffer before attempting to
433 // do stencil-based operations. 316 // do stencil-based operations.
434 } 317 }
435 318
436 // Allocate a new IOSurface, which is the GPU resource that can be 319 bool allocated_color_buffer = storage_provider_->AllocateColorBufferStorage(
437 // shared across processes. 320 static_cast<CGLContextObj>(context_->GetHandle()),
438 base::ScopedCFTypeRef<CFMutableDictionaryRef> properties; 321 rounded_size_);
439 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, 322 if (!allocated_color_buffer) {
440 0, 323 DLOG(ERROR) << "Failed to allocate color buffer storage.";
441 &kCFTypeDictionaryKeyCallBacks, 324 DestroyFramebuffer();
442 &kCFTypeDictionaryValueCallBacks));
443 AddIntegerValue(properties,
444 kIOSurfaceWidth,
445 rounded_size_.width());
446 AddIntegerValue(properties,
447 kIOSurfaceHeight,
448 rounded_size_.height());
449 AddIntegerValue(properties,
450 kIOSurfaceBytesPerElement, 4);
451 AddBooleanValue(properties,
452 kIOSurfaceIsGlobal, true);
453 // I believe we should be able to unreference the IOSurfaces without
454 // synchronizing with the browser process because they are
455 // ultimately reference counted by the operating system.
456 io_surface_.reset(IOSurfaceCreate(properties));
457 io_surface_handle_ = IOSurfaceGetID(io_surface_);
458
459 // Don't think we need to identify a plane.
460 GLuint plane = 0;
461 CGLError cglerror =
462 CGLTexImageIOSurface2D(
463 static_cast<CGLContextObj>(context_->GetHandle()),
464 target,
465 GL_RGBA,
466 rounded_size_.width(),
467 rounded_size_.height(),
468 GL_BGRA,
469 GL_UNSIGNED_INT_8_8_8_8_REV,
470 io_surface_.get(),
471 plane);
472 if (cglerror != kCGLNoError) {
473 UnrefIOSurface();
474 return; 325 return;
475 } 326 }
476 327
477 glFlush();
478
479 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 328 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
480 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 329 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
481 DLOG(ERROR) << "Framebuffer was incomplete: " << status; 330 DLOG(ERROR) << "Framebuffer was incomplete: " << status;
482 UnrefIOSurface(); 331 DestroyFramebuffer();
483 return; 332 return;
484 } 333 }
485 334
335 has_complete_framebuffer_ = true;
336
486 glBindTexture(target, previous_texture_id); 337 glBindTexture(target, previous_texture_id);
487 // The FBO remains bound for this GL context. 338 // The FBO remains bound for this GL context.
488 } 339 }
489 340
490 // A subclass of GLSurfaceOSMesa that doesn't print an error message when 341 // A subclass of GLSurfaceOSMesa that doesn't print an error message when
491 // SwapBuffers() is called. 342 // SwapBuffers() is called.
492 class DRTSurfaceOSMesa : public gfx::GLSurfaceOSMesa { 343 class DRTSurfaceOSMesa : public gfx::GLSurfaceOSMesa {
493 public: 344 public:
494 // Size doesn't matter, the surface is resized to the right size later. 345 // Size doesn't matter, the surface is resized to the right size later.
495 DRTSurfaceOSMesa() : GLSurfaceOSMesa(GL_RGBA, gfx::Size(1, 1)) {} 346 DRTSurfaceOSMesa() : GLSurfaceOSMesa(GL_RGBA, gfx::Size(1, 1)) {}
496 347
497 // Implement a subset of GLSurface. 348 // Implement a subset of GLSurface.
498 virtual bool SwapBuffers() OVERRIDE; 349 virtual bool SwapBuffers() OVERRIDE;
499 350
500 private: 351 private:
501 virtual ~DRTSurfaceOSMesa() {} 352 virtual ~DRTSurfaceOSMesa() {}
502 DISALLOW_COPY_AND_ASSIGN(DRTSurfaceOSMesa); 353 DISALLOW_COPY_AND_ASSIGN(DRTSurfaceOSMesa);
503 }; 354 };
504 355
505 bool DRTSurfaceOSMesa::SwapBuffers() { 356 bool DRTSurfaceOSMesa::SwapBuffers() {
506 return true; 357 return true;
507 } 358 }
508 359
509 bool g_allow_os_mesa = false; 360 bool g_allow_os_mesa = false;
510 361
511 } // namespace 362 ImageTransportSurfaceFBO::StorageProvider* MakeThing();
512 363
513 // static 364 // static
514 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface( 365 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface(
515 GpuChannelManager* manager, 366 GpuChannelManager* manager,
516 GpuCommandBufferStub* stub, 367 GpuCommandBufferStub* stub,
517 const gfx::GLSurfaceHandle& surface_handle) { 368 const gfx::GLSurfaceHandle& surface_handle) {
518 DCHECK(surface_handle.transport_type == gfx::NATIVE_DIRECT || 369 DCHECK(surface_handle.transport_type == gfx::NATIVE_DIRECT ||
519 surface_handle.transport_type == gfx::NATIVE_TRANSPORT); 370 surface_handle.transport_type == gfx::NATIVE_TRANSPORT);
520 371
521 switch (gfx::GetGLImplementation()) { 372 switch (gfx::GetGLImplementation()) {
522 case gfx::kGLImplementationDesktopGL: 373 case gfx::kGLImplementationDesktopGL:
523 case gfx::kGLImplementationAppleGL: 374 case gfx::kGLImplementationAppleGL:
524 return scoped_refptr<gfx::GLSurface>(new IOSurfaceImageTransportSurface( 375 return scoped_refptr<gfx::GLSurface>(new ImageTransportSurfaceFBO(
525 manager, stub, surface_handle.handle)); 376 MakeThing(), manager, stub, surface_handle.handle));
526
527 default: 377 default:
528 // Content shell in DRT mode spins up a gpu process which needs an 378 // Content shell in DRT mode spins up a gpu process which needs an
529 // image transport surface, but that surface isn't used to read pixel 379 // image transport surface, but that surface isn't used to read pixel
530 // baselines. So this is mostly a dummy surface. 380 // baselines. So this is mostly a dummy surface.
531 if (!g_allow_os_mesa) { 381 if (!g_allow_os_mesa) {
532 NOTREACHED(); 382 NOTREACHED();
533 return scoped_refptr<gfx::GLSurface>(); 383 return scoped_refptr<gfx::GLSurface>();
534 } 384 }
535 scoped_refptr<gfx::GLSurface> surface(new DRTSurfaceOSMesa()); 385 scoped_refptr<gfx::GLSurface> surface(new DRTSurfaceOSMesa());
536 if (!surface.get() || !surface->Initialize()) 386 if (!surface.get() || !surface->Initialize())
537 return surface; 387 return surface;
538 return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface( 388 return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface(
539 manager, stub, surface.get())); 389 manager, stub, surface.get()));
540 } 390 }
541 } 391 }
542 392
543 // static 393 // static
544 void ImageTransportSurface::SetAllowOSMesaForTesting(bool allow) { 394 void ImageTransportSurface::SetAllowOSMesaForTesting(bool allow) {
545 g_allow_os_mesa = allow; 395 g_allow_os_mesa = allow;
546 } 396 }
547 397
548 } // namespace content 398 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/image_transport_surface_mac.h ('k') | content/common/view_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698