| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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_fbo_mac.h" | 5 #include "content/common/gpu/image_transport_surface_fbo_mac.h" |
| 6 | 6 |
| 7 #include "content/common/gpu/gpu_messages.h" | 7 #include "content/common/gpu/gpu_messages.h" |
| 8 #include "content/common/gpu/image_transport_surface_calayer_mac.h" | 8 #include "content/common/gpu/image_transport_surface_calayer_mac.h" |
| 9 #include "content/common/gpu/image_transport_surface_iosurface_mac.h" | 9 #include "content/common/gpu/image_transport_surface_iosurface_mac.h" |
| 10 #include "ui/base/cocoa/remote_layer_api.h" | 10 #include "ui/base/cocoa/remote_layer_api.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 gfx::PluginWindowHandle handle) | 21 gfx::PluginWindowHandle handle) |
| 22 : backbuffer_suggested_allocation_(true), | 22 : backbuffer_suggested_allocation_(true), |
| 23 frontbuffer_suggested_allocation_(true), | 23 frontbuffer_suggested_allocation_(true), |
| 24 fbo_id_(0), | 24 fbo_id_(0), |
| 25 texture_id_(0), | 25 texture_id_(0), |
| 26 depth_stencil_renderbuffer_id_(0), | 26 depth_stencil_renderbuffer_id_(0), |
| 27 has_complete_framebuffer_(false), | 27 has_complete_framebuffer_(false), |
| 28 context_(NULL), | 28 context_(NULL), |
| 29 scale_factor_(1.f), | 29 scale_factor_(1.f), |
| 30 made_current_(false), | 30 made_current_(false), |
| 31 is_swap_buffers_send_pending_(false) { | 31 is_swap_buffers_pending_(false), |
| 32 did_unschedule_(false) { |
| 32 if (ui::RemoteLayerAPISupported()) | 33 if (ui::RemoteLayerAPISupported()) |
| 33 storage_provider_.reset(new CALayerStorageProvider(this)); | 34 storage_provider_.reset(new CALayerStorageProvider(this)); |
| 34 else | 35 else |
| 35 storage_provider_.reset(new IOSurfaceStorageProvider(this)); | 36 storage_provider_.reset(new IOSurfaceStorageProvider(this)); |
| 36 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); | 37 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); |
| 37 } | 38 } |
| 38 | 39 |
| 39 ImageTransportSurfaceFBO::~ImageTransportSurfaceFBO() { | 40 ImageTransportSurfaceFBO::~ImageTransportSurfaceFBO() { |
| 40 } | 41 } |
| 41 | 42 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 54 return true; | 55 return true; |
| 55 } | 56 } |
| 56 | 57 |
| 57 void ImageTransportSurfaceFBO::Destroy() { | 58 void ImageTransportSurfaceFBO::Destroy() { |
| 58 DestroyFramebuffer(); | 59 DestroyFramebuffer(); |
| 59 | 60 |
| 60 helper_->Destroy(); | 61 helper_->Destroy(); |
| 61 } | 62 } |
| 62 | 63 |
| 63 bool ImageTransportSurfaceFBO::DeferDraws() { | 64 bool ImageTransportSurfaceFBO::DeferDraws() { |
| 64 storage_provider_->WillWriteToBackbuffer(); | 65 // The command buffer hit a draw/clear command that could clobber the |
| 65 // We should not have a pending send when we are drawing the next frame. | 66 // IOSurface in use by an earlier SwapBuffers. If a Swap is pending, abort |
| 66 DCHECK(!is_swap_buffers_send_pending_); | 67 // processing of the command by returning true and unschedule until the Swap |
| 68 // Ack arrives. |
| 69 if(did_unschedule_) |
| 70 return true; // Still unscheduled, so just return true. |
| 71 if (is_swap_buffers_pending_) { |
| 72 did_unschedule_ = true; |
| 73 helper_->SetScheduled(false); |
| 74 return true; |
| 75 } |
| 67 return false; | 76 return false; |
| 68 } | 77 } |
| 69 | 78 |
| 70 bool ImageTransportSurfaceFBO::IsOffscreen() { | 79 bool ImageTransportSurfaceFBO::IsOffscreen() { |
| 71 return false; | 80 return false; |
| 72 } | 81 } |
| 73 | 82 |
| 74 bool ImageTransportSurfaceFBO::OnMakeCurrent(gfx::GLContext* context) { | 83 bool ImageTransportSurfaceFBO::OnMakeCurrent(gfx::GLContext* context) { |
| 75 context_ = context; | 84 context_ = context; |
| 76 | 85 |
| 77 if (made_current_) | 86 if (made_current_) |
| 78 return true; | 87 return true; |
| 79 | 88 |
| 80 OnResize(gfx::Size(1, 1), 1.f); | 89 OnResize(gfx::Size(1, 1), 1.f); |
| 81 | 90 |
| 82 made_current_ = true; | 91 made_current_ = true; |
| 83 return true; | 92 return true; |
| 84 } | 93 } |
| 85 | 94 |
| 86 unsigned int ImageTransportSurfaceFBO::GetBackingFrameBufferObject() { | 95 unsigned int ImageTransportSurfaceFBO::GetBackingFrameBufferObject() { |
| 87 return fbo_id_; | 96 return fbo_id_; |
| 88 } | 97 } |
| 89 | 98 |
| 90 bool ImageTransportSurfaceFBO::SetBackbufferAllocation(bool allocation) { | 99 bool ImageTransportSurfaceFBO::SetBackbufferAllocation(bool allocation) { |
| 91 if (backbuffer_suggested_allocation_ == allocation) | 100 if (backbuffer_suggested_allocation_ == allocation) |
| 92 return true; | 101 return true; |
| 93 backbuffer_suggested_allocation_ = allocation; | 102 backbuffer_suggested_allocation_ = allocation; |
| 94 AdjustBufferAllocation(); | 103 AdjustBufferAllocation(); |
| 95 if (!allocation) | |
| 96 storage_provider_->DiscardBackbuffer(); | |
| 97 return true; | 104 return true; |
| 98 } | 105 } |
| 99 | 106 |
| 100 void ImageTransportSurfaceFBO::SetFrontbufferAllocation(bool allocation) { | 107 void ImageTransportSurfaceFBO::SetFrontbufferAllocation(bool allocation) { |
| 101 if (frontbuffer_suggested_allocation_ == allocation) | 108 if (frontbuffer_suggested_allocation_ == allocation) |
| 102 return; | 109 return; |
| 103 frontbuffer_suggested_allocation_ = allocation; | 110 frontbuffer_suggested_allocation_ = allocation; |
| 104 AdjustBufferAllocation(); | 111 AdjustBufferAllocation(); |
| 105 } | 112 } |
| 106 | 113 |
| 107 void ImageTransportSurfaceFBO::AdjustBufferAllocation() { | 114 void ImageTransportSurfaceFBO::AdjustBufferAllocation() { |
| 108 // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is | 115 // On mac, the frontbuffer and backbuffer are the same buffer. The buffer is |
| 109 // free'd when both the browser and gpu processes have Unref'd the IOSurface. | 116 // free'd when both the browser and gpu processes have Unref'd the IOSurface. |
| 110 if (!backbuffer_suggested_allocation_ && | 117 if (!backbuffer_suggested_allocation_ && |
| 111 !frontbuffer_suggested_allocation_ && | 118 !frontbuffer_suggested_allocation_ && |
| 112 has_complete_framebuffer_) { | 119 has_complete_framebuffer_) { |
| 113 DestroyFramebuffer(); | 120 DestroyFramebuffer(); |
| 114 helper_->Suspend(); | 121 helper_->Suspend(); |
| 115 } else if (backbuffer_suggested_allocation_ && !has_complete_framebuffer_) { | 122 } else if (backbuffer_suggested_allocation_ && !has_complete_framebuffer_) { |
| 116 CreateFramebuffer(); | 123 CreateFramebuffer(); |
| 117 } | 124 } |
| 118 } | 125 } |
| 119 | 126 |
| 120 bool ImageTransportSurfaceFBO::SwapBuffers() { | 127 bool ImageTransportSurfaceFBO::SwapBuffers() { |
| 121 DCHECK(backbuffer_suggested_allocation_); | 128 DCHECK(backbuffer_suggested_allocation_); |
| 122 if (!frontbuffer_suggested_allocation_) | 129 if (!frontbuffer_suggested_allocation_) |
| 123 return true; | 130 return true; |
| 124 glFlush(); | 131 glFlush(); |
| 125 | 132 |
| 126 // It is the responsibility of the storage provider to send the swap IPC. | 133 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| 127 is_swap_buffers_send_pending_ = true; | 134 params.surface_handle = storage_provider_->GetSurfaceHandle(); |
| 128 storage_provider_->SwapBuffers(size_, scale_factor_); | 135 params.size = GetSize(); |
| 136 params.scale_factor = scale_factor_; |
| 137 params.latency_info.swap(latency_info_); |
| 138 helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| 139 |
| 140 DCHECK(!is_swap_buffers_pending_); |
| 141 is_swap_buffers_pending_ = true; |
| 142 |
| 143 storage_provider_->WillSwapBuffers(); |
| 129 return true; | 144 return true; |
| 130 } | 145 } |
| 131 | 146 |
| 132 void ImageTransportSurfaceFBO::SendSwapBuffers(uint64 surface_handle, | |
| 133 const gfx::Size pixel_size, | |
| 134 float scale_factor) { | |
| 135 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | |
| 136 params.surface_handle = surface_handle; | |
| 137 params.size = pixel_size; | |
| 138 params.scale_factor = scale_factor; | |
| 139 params.latency_info.swap(latency_info_); | |
| 140 helper_->SendAcceleratedSurfaceBuffersSwapped(params); | |
| 141 is_swap_buffers_send_pending_ = false; | |
| 142 } | |
| 143 | |
| 144 bool ImageTransportSurfaceFBO::PostSubBuffer( | 147 bool ImageTransportSurfaceFBO::PostSubBuffer( |
| 145 int x, int y, int width, int height) { | 148 int x, int y, int width, int height) { |
| 146 // Mac does not support sub-buffer swaps. | 149 // Mac does not support sub-buffer swaps. |
| 147 NOTREACHED(); | 150 NOTREACHED(); |
| 148 return false; | 151 return false; |
| 149 } | 152 } |
| 150 | 153 |
| 151 bool ImageTransportSurfaceFBO::SupportsPostSubBuffer() { | 154 bool ImageTransportSurfaceFBO::SupportsPostSubBuffer() { |
| 152 return true; | 155 return true; |
| 153 } | 156 } |
| 154 | 157 |
| 155 gfx::Size ImageTransportSurfaceFBO::GetSize() { | 158 gfx::Size ImageTransportSurfaceFBO::GetSize() { |
| 156 return size_; | 159 return size_; |
| 157 } | 160 } |
| 158 | 161 |
| 159 void* ImageTransportSurfaceFBO::GetHandle() { | 162 void* ImageTransportSurfaceFBO::GetHandle() { |
| 160 return NULL; | 163 return NULL; |
| 161 } | 164 } |
| 162 | 165 |
| 163 void* ImageTransportSurfaceFBO::GetDisplay() { | 166 void* ImageTransportSurfaceFBO::GetDisplay() { |
| 164 return NULL; | 167 return NULL; |
| 165 } | 168 } |
| 166 | 169 |
| 167 void ImageTransportSurfaceFBO::OnBufferPresented( | 170 void ImageTransportSurfaceFBO::OnBufferPresented( |
| 168 const AcceleratedSurfaceMsg_BufferPresented_Params& params) { | 171 const AcceleratedSurfaceMsg_BufferPresented_Params& params) { |
| 169 context_->share_group()->SetRendererID(params.renderer_id); | 172 context_->share_group()->SetRendererID(params.renderer_id); |
| 170 storage_provider_->SwapBuffersAckedByBrowser(); | 173 storage_provider_->CanFreeSwappedBuffer(); |
| 174 } |
| 175 |
| 176 void ImageTransportSurfaceFBO::UnblockContextAfterPendingSwap() { |
| 177 DCHECK(is_swap_buffers_pending_); |
| 178 is_swap_buffers_pending_ = false; |
| 179 if (did_unschedule_) { |
| 180 did_unschedule_ = false; |
| 181 helper_->SetScheduled(true); |
| 182 } |
| 171 } | 183 } |
| 172 | 184 |
| 173 void ImageTransportSurfaceFBO::OnResize(gfx::Size size, | 185 void ImageTransportSurfaceFBO::OnResize(gfx::Size size, |
| 174 float scale_factor) { | 186 float scale_factor) { |
| 175 TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::OnResize", | 187 TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::OnResize", |
| 176 "old_width", size_.width(), "new_width", size.width()); | 188 "old_width", size_.width(), "new_width", size.width()); |
| 177 // Caching |context_| from OnMakeCurrent. It should still be current. | 189 // Caching |context_| from OnMakeCurrent. It should still be current. |
| 178 DCHECK(context_->IsCurrent(this)); | 190 DCHECK(context_->IsCurrent(this)); |
| 179 | 191 |
| 180 size_ = size; | 192 size_ = size; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 return; | 325 return; |
| 314 } | 326 } |
| 315 | 327 |
| 316 has_complete_framebuffer_ = true; | 328 has_complete_framebuffer_ = true; |
| 317 | 329 |
| 318 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, previous_texture_id); | 330 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, previous_texture_id); |
| 319 // The FBO remains bound for this GL context. | 331 // The FBO remains bound for this GL context. |
| 320 } | 332 } |
| 321 | 333 |
| 322 } // namespace content | 334 } // namespace content |
| OLD | NEW |