OLD | NEW |
---|---|
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.h" |
6 | 6 |
7 #include "base/mac/scoped_cftyperef.h" | 7 #include "base/mac/scoped_cftyperef.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "content/common/gpu/gpu_command_buffer_stub.h" | |
9 #include "content/common/gpu/gpu_messages.h" | 10 #include "content/common/gpu/gpu_messages.h" |
10 #include "ui/gfx/native_widget_types.h" | 11 #include "ui/gfx/native_widget_types.h" |
11 #include "ui/gl/gl_bindings.h" | 12 #include "ui/gl/gl_bindings.h" |
12 #include "ui/gl/gl_context.h" | 13 #include "ui/gl/gl_context.h" |
13 #include "ui/gl/gl_implementation.h" | 14 #include "ui/gl/gl_implementation.h" |
14 #include "ui/gl/gl_surface_cgl.h" | 15 #include "ui/gl/gl_surface_cgl.h" |
15 #include "ui/gl/gl_surface_osmesa.h" | 16 #include "ui/gl/gl_surface_osmesa.h" |
16 #include "ui/surface/io_surface_support_mac.h" | 17 #include "ui/surface/io_surface_support_mac.h" |
17 | 18 |
18 namespace content { | 19 namespace content { |
19 namespace { | 20 namespace { |
20 | 21 |
21 // IOSurface dimensions will be rounded up to a multiple of this value in order | 22 // IOSurface dimensions will be rounded up to a multiple of this value in order |
22 // to reduce memory thrashing during resize. This must be a power of 2. | 23 // to reduce memory thrashing during resize. This must be a power of 2. |
23 const uint32 kIOSurfaceDimensionRoundup = 64; | 24 const uint32 kIOSurfaceDimensionRoundup = 64; |
24 | 25 |
25 int RoundUpSurfaceDimension(int number) { | 26 int RoundUpSurfaceDimension(int number) { |
26 DCHECK(number >= 0); | 27 DCHECK(number >= 0); |
27 // Cast into unsigned space for portable bitwise ops. | 28 // Cast into unsigned space for portable bitwise ops. |
28 uint32 unsigned_number = static_cast<uint32>(number); | 29 uint32 unsigned_number = static_cast<uint32>(number); |
29 uint32 roundup_sub_1 = kIOSurfaceDimensionRoundup - 1; | 30 uint32 roundup_sub_1 = kIOSurfaceDimensionRoundup - 1; |
30 unsigned_number = (unsigned_number + roundup_sub_1) & ~roundup_sub_1; | 31 unsigned_number = (unsigned_number + roundup_sub_1) & ~roundup_sub_1; |
31 return static_cast<int>(unsigned_number); | 32 return static_cast<int>(unsigned_number); |
32 } | 33 } |
33 | 34 |
34 // We are backed by an offscreen surface for the purposes of creating | 35 // We are backed by an offscreen surface for the purposes of creating |
35 // a context, but use FBOs to render to texture backed IOSurface | 36 // a context, but use FBOs to render to texture backed IOSurface |
36 class IOSurfaceImageTransportSurface : public gfx::NoOpGLSurfaceCGL, | 37 class IOSurfaceImageTransportSurface |
37 public ImageTransportSurface { | 38 : public gfx::NoOpGLSurfaceCGL, |
39 public ImageTransportSurface, | |
40 public GpuCommandBufferStub::DestructionObserver { | |
38 public: | 41 public: |
39 IOSurfaceImageTransportSurface(GpuChannelManager* manager, | 42 IOSurfaceImageTransportSurface(GpuChannelManager* manager, |
40 GpuCommandBufferStub* stub, | 43 GpuCommandBufferStub* stub, |
41 gfx::PluginWindowHandle handle); | 44 gfx::PluginWindowHandle handle); |
42 | 45 |
43 // GLSurface implementation | 46 // GLSurface implementation |
44 virtual bool Initialize() OVERRIDE; | 47 virtual bool Initialize() OVERRIDE; |
45 virtual void Destroy() OVERRIDE; | 48 virtual void Destroy() OVERRIDE; |
46 virtual bool DeferDraws() OVERRIDE; | 49 virtual bool DeferDraws() OVERRIDE; |
47 virtual bool IsOffscreen() OVERRIDE; | 50 virtual bool IsOffscreen() OVERRIDE; |
48 virtual bool SwapBuffers() OVERRIDE; | 51 virtual bool SwapBuffers() OVERRIDE; |
49 virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE; | 52 virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE; |
50 virtual std::string GetExtensions() OVERRIDE; | 53 virtual std::string GetExtensions() OVERRIDE; |
51 virtual gfx::Size GetSize() OVERRIDE; | 54 virtual gfx::Size GetSize() OVERRIDE; |
52 virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE; | 55 virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE; |
53 virtual unsigned int GetBackingFrameBufferObject() OVERRIDE; | 56 virtual unsigned int GetBackingFrameBufferObject() OVERRIDE; |
54 virtual bool SetBackbufferAllocation(bool allocated) OVERRIDE; | 57 virtual bool SetBackbufferAllocation(bool allocated) OVERRIDE; |
55 virtual void SetFrontbufferAllocation(bool allocated) OVERRIDE; | 58 virtual void SetFrontbufferAllocation(bool allocated) OVERRIDE; |
56 | 59 |
57 protected: | 60 protected: |
58 // ImageTransportSurface implementation | 61 // ImageTransportSurface implementation |
59 virtual void OnBufferPresented( | 62 virtual void OnBufferPresented( |
60 const AcceleratedSurfaceMsg_BufferPresented_Params& params) OVERRIDE; | 63 const AcceleratedSurfaceMsg_BufferPresented_Params& params) OVERRIDE; |
61 virtual void OnResizeViewACK() OVERRIDE; | 64 virtual void OnResizeViewACK() OVERRIDE; |
62 virtual void OnResize(gfx::Size size, float scale_factor) OVERRIDE; | 65 virtual void OnResize(gfx::Size size, float scale_factor) OVERRIDE; |
63 virtual void SetLatencyInfo(const ui::LatencyInfo&) OVERRIDE; | 66 virtual void SetLatencyInfo(const ui::LatencyInfo&) OVERRIDE; |
64 | 67 |
68 // GpuCommandBufferStub::DestructionObserver implementation. | |
69 virtual void OnWillDestroyStub() OVERRIDE; | |
70 | |
65 private: | 71 private: |
66 virtual ~IOSurfaceImageTransportSurface() OVERRIDE; | 72 virtual ~IOSurfaceImageTransportSurface() OVERRIDE; |
67 | 73 |
68 void AdjustBufferAllocation(); | 74 void AdjustBufferAllocation(); |
69 void UnrefIOSurface(); | 75 void UnrefIOSurface(); |
70 void CreateIOSurface(); | 76 void CreateIOSurface(); |
71 | 77 |
72 // Tracks the current buffer allocation state. | 78 // Tracks the current buffer allocation state. |
73 bool backbuffer_suggested_allocation_; | 79 bool backbuffer_suggested_allocation_; |
74 bool frontbuffer_suggested_allocation_; | 80 bool frontbuffer_suggested_allocation_; |
(...skipping 19 matching lines...) Expand all Loading... | |
94 // Whether a SwapBuffers is pending. | 100 // Whether a SwapBuffers is pending. |
95 bool is_swap_buffers_pending_; | 101 bool is_swap_buffers_pending_; |
96 | 102 |
97 // Whether we unscheduled command buffer because of pending SwapBuffers. | 103 // Whether we unscheduled command buffer because of pending SwapBuffers. |
98 bool did_unschedule_; | 104 bool did_unschedule_; |
99 | 105 |
100 ui::LatencyInfo latency_info_; | 106 ui::LatencyInfo latency_info_; |
101 | 107 |
102 scoped_ptr<ImageTransportHelper> helper_; | 108 scoped_ptr<ImageTransportHelper> helper_; |
103 | 109 |
110 bool added_observer_; | |
111 | |
104 DISALLOW_COPY_AND_ASSIGN(IOSurfaceImageTransportSurface); | 112 DISALLOW_COPY_AND_ASSIGN(IOSurfaceImageTransportSurface); |
105 }; | 113 }; |
106 | 114 |
107 void AddBooleanValue(CFMutableDictionaryRef dictionary, | 115 void AddBooleanValue(CFMutableDictionaryRef dictionary, |
108 const CFStringRef key, | 116 const CFStringRef key, |
109 bool value) { | 117 bool value) { |
110 CFDictionaryAddValue(dictionary, key, | 118 CFDictionaryAddValue(dictionary, key, |
111 (value ? kCFBooleanTrue : kCFBooleanFalse)); | 119 (value ? kCFBooleanTrue : kCFBooleanFalse)); |
112 } | 120 } |
113 | 121 |
(...skipping 12 matching lines...) Expand all Loading... | |
126 : gfx::NoOpGLSurfaceCGL(gfx::Size(1, 1)), | 134 : gfx::NoOpGLSurfaceCGL(gfx::Size(1, 1)), |
127 backbuffer_suggested_allocation_(true), | 135 backbuffer_suggested_allocation_(true), |
128 frontbuffer_suggested_allocation_(true), | 136 frontbuffer_suggested_allocation_(true), |
129 fbo_id_(0), | 137 fbo_id_(0), |
130 texture_id_(0), | 138 texture_id_(0), |
131 io_surface_handle_(0), | 139 io_surface_handle_(0), |
132 context_(NULL), | 140 context_(NULL), |
133 scale_factor_(1.f), | 141 scale_factor_(1.f), |
134 made_current_(false), | 142 made_current_(false), |
135 is_swap_buffers_pending_(false), | 143 is_swap_buffers_pending_(false), |
136 did_unschedule_(false) { | 144 did_unschedule_(false), |
145 added_observer_(false) { | |
137 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); | 146 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); |
138 } | 147 } |
139 | 148 |
140 IOSurfaceImageTransportSurface::~IOSurfaceImageTransportSurface() { | 149 IOSurfaceImageTransportSurface::~IOSurfaceImageTransportSurface() { |
141 Destroy(); | |
142 } | 150 } |
143 | 151 |
144 bool IOSurfaceImageTransportSurface::Initialize() { | 152 bool IOSurfaceImageTransportSurface::Initialize() { |
145 // Only support IOSurfaces if the GL implementation is the native desktop GL. | 153 // Only support IOSurfaces if the GL implementation is the native desktop GL. |
146 // IO surfaces will not work with, for example, OSMesa software renderer | 154 // IO surfaces will not work with, for example, OSMesa software renderer |
147 // GL contexts. | 155 // GL contexts. |
148 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL && | 156 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL && |
149 gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL) | 157 gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL) |
150 return false; | 158 return false; |
151 | 159 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 scale_factor_ = scale_factor; | 314 scale_factor_ = scale_factor; |
307 | 315 |
308 CreateIOSurface(); | 316 CreateIOSurface(); |
309 } | 317 } |
310 | 318 |
311 void IOSurfaceImageTransportSurface::SetLatencyInfo( | 319 void IOSurfaceImageTransportSurface::SetLatencyInfo( |
312 const ui::LatencyInfo& latency_info) { | 320 const ui::LatencyInfo& latency_info) { |
313 latency_info_ = latency_info; | 321 latency_info_ = latency_info; |
314 } | 322 } |
315 | 323 |
324 void IOSurfaceImageTransportSurface::OnWillDestroyStub() { | |
325 helper_->stub()->RemoveDestructionObserver(this); | |
326 Destroy(); | |
327 } | |
328 | |
316 void IOSurfaceImageTransportSurface::UnrefIOSurface() { | 329 void IOSurfaceImageTransportSurface::UnrefIOSurface() { |
317 // If we have resources to destroy, then make sure that we have a current | 330 // If we have resources to destroy, then make sure that we have a current |
318 // context which we can use to delete the resources. | 331 // context which we can use to delete the resources. |
319 if (context_ || fbo_id_ || texture_id_) { | 332 if (context_ || fbo_id_ || texture_id_) { |
320 DCHECK(gfx::GLContext::GetCurrent() == context_); | 333 DCHECK(gfx::GLContext::GetCurrent() == context_); |
321 DCHECK(context_->IsCurrent(this)); | 334 DCHECK(context_->IsCurrent(this)); |
322 DCHECK(CGLGetCurrentContext()); | 335 DCHECK(CGLGetCurrentContext()); |
323 } | 336 } |
324 | 337 |
325 if (fbo_id_) { | 338 if (fbo_id_) { |
326 glDeleteFramebuffersEXT(1, &fbo_id_); | 339 glDeleteFramebuffersEXT(1, &fbo_id_); |
327 fbo_id_ = 0; | 340 fbo_id_ = 0; |
328 } | 341 } |
329 | 342 |
330 if (texture_id_) { | 343 if (texture_id_) { |
331 glDeleteTextures(1, &texture_id_); | 344 glDeleteTextures(1, &texture_id_); |
332 texture_id_ = 0; | 345 texture_id_ = 0; |
333 } | 346 } |
334 | 347 |
335 io_surface_.reset(); | 348 io_surface_.reset(); |
336 io_surface_handle_ = 0; | 349 io_surface_handle_ = 0; |
337 } | 350 } |
338 | 351 |
339 void IOSurfaceImageTransportSurface::CreateIOSurface() { | 352 void IOSurfaceImageTransportSurface::CreateIOSurface() { |
340 gfx::Size new_rounded_size(RoundUpSurfaceDimension(size_.width()), | 353 gfx::Size new_rounded_size(RoundUpSurfaceDimension(size_.width()), |
341 RoundUpSurfaceDimension(size_.height())); | 354 RoundUpSurfaceDimension(size_.height())); |
342 | 355 |
356 if (!added_observer_) { | |
357 helper_->stub()->AddDestructionObserver(this); | |
piman
2013/06/05 00:05:33
Why not do that always in Initialize?
Destroy seem
no sievers
2013/06/05 00:19:05
Done.
I think I was under the false impression th
| |
358 added_observer_ = true; | |
359 } | |
360 | |
343 // Only recreate surface when the rounded up size has changed. | 361 // Only recreate surface when the rounded up size has changed. |
344 if (io_surface_.get() && new_rounded_size == rounded_size_) | 362 if (io_surface_.get() && new_rounded_size == rounded_size_) |
345 return; | 363 return; |
346 | 364 |
347 // This trace event is used in gpu_feature_browsertest.cc - the test will need | 365 // This trace event is used in gpu_feature_browsertest.cc - the test will need |
348 // to be updated if this event is changed or moved. | 366 // to be updated if this event is changed or moved. |
349 TRACE_EVENT2("gpu", "IOSurfaceImageTransportSurface::CreateIOSurface", | 367 TRACE_EVENT2("gpu", "IOSurfaceImageTransportSurface::CreateIOSurface", |
350 "width", new_rounded_size.width(), | 368 "width", new_rounded_size.width(), |
351 "height", new_rounded_size.height()); | 369 "height", new_rounded_size.height()); |
352 | 370 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 manager, stub, surface.get(), false)); | 502 manager, stub, surface.get(), false)); |
485 } | 503 } |
486 } | 504 } |
487 | 505 |
488 // static | 506 // static |
489 void ImageTransportSurface::SetAllowOSMesaForTesting(bool allow) { | 507 void ImageTransportSurface::SetAllowOSMesaForTesting(bool allow) { |
490 g_allow_os_mesa = allow; | 508 g_allow_os_mesa = allow; |
491 } | 509 } |
492 | 510 |
493 } // namespace content | 511 } // namespace content |
OLD | NEW |