Chromium Code Reviews| 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 |