| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "cc/output/output_surface.h" | 5 #include "cc/output/output_surface.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 uint64_t share_group_tracing_guid_; | 115 uint64_t share_group_tracing_guid_; |
| 116 | 116 |
| 117 DISALLOW_COPY_AND_ASSIGN(SkiaGpuTraceMemoryDump); | 117 DISALLOW_COPY_AND_ASSIGN(SkiaGpuTraceMemoryDump); |
| 118 }; | 118 }; |
| 119 | 119 |
| 120 } // namespace | 120 } // namespace |
| 121 | 121 |
| 122 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) | 122 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) |
| 123 : context_provider_(std::move(context_provider)), weak_ptr_factory_(this) { | 123 : context_provider_(std::move(context_provider)), weak_ptr_factory_(this) { |
| 124 DCHECK(context_provider_); | 124 DCHECK(context_provider_); |
| 125 client_thread_checker_.DetachFromThread(); | 125 thread_checker_.DetachFromThread(); |
| 126 } | 126 } |
| 127 | 127 |
| 128 OutputSurface::OutputSurface( | 128 OutputSurface::OutputSurface( |
| 129 std::unique_ptr<SoftwareOutputDevice> software_device) | 129 std::unique_ptr<SoftwareOutputDevice> software_device) |
| 130 : software_device_(std::move(software_device)), weak_ptr_factory_(this) { | 130 : software_device_(std::move(software_device)), weak_ptr_factory_(this) { |
| 131 DCHECK(software_device_); | 131 DCHECK(software_device_); |
| 132 client_thread_checker_.DetachFromThread(); | 132 thread_checker_.DetachFromThread(); |
| 133 } | 133 } |
| 134 | 134 |
| 135 OutputSurface::OutputSurface( | 135 OutputSurface::OutputSurface( |
| 136 scoped_refptr<VulkanContextProvider> vulkan_context_provider) | 136 scoped_refptr<VulkanContextProvider> vulkan_context_provider) |
| 137 : vulkan_context_provider_(vulkan_context_provider), | 137 : vulkan_context_provider_(vulkan_context_provider), |
| 138 weak_ptr_factory_(this) { | 138 weak_ptr_factory_(this) { |
| 139 DCHECK(vulkan_context_provider_); | 139 DCHECK(vulkan_context_provider_); |
| 140 client_thread_checker_.DetachFromThread(); | 140 thread_checker_.DetachFromThread(); |
| 141 } | 141 } |
| 142 | 142 |
| 143 OutputSurface::~OutputSurface() { | 143 OutputSurface::~OutputSurface() { |
| 144 if (client_) | 144 // Is destroyed on the thread it is bound to. |
| 145 DetachFromClientInternal(); | 145 DCHECK(thread_checker_.CalledOnValidThread()); |
| 146 |
| 147 if (!client_) |
| 148 return; |
| 149 |
| 150 // Unregister any dump provider. Safe to call (no-op) if we have not yet |
| 151 // registered. |
| 152 if (base::ThreadTaskRunnerHandle::IsSet()) { |
| 153 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
| 154 this); |
| 155 } |
| 156 |
| 157 if (context_provider_) { |
| 158 context_provider_->SetLostContextCallback( |
| 159 ContextProvider::LostContextCallback()); |
| 160 } |
| 146 } | 161 } |
| 147 | 162 |
| 148 bool OutputSurface::HasExternalStencilTest() const { | |
| 149 return false; | |
| 150 } | |
| 151 | |
| 152 void OutputSurface::ApplyExternalStencil() {} | |
| 153 | |
| 154 bool OutputSurface::BindToClient(OutputSurfaceClient* client) { | 163 bool OutputSurface::BindToClient(OutputSurfaceClient* client) { |
| 155 DCHECK(client_thread_checker_.CalledOnValidThread()); | 164 DCHECK(thread_checker_.CalledOnValidThread()); |
| 156 DCHECK(client); | 165 DCHECK(client); |
| 157 DCHECK(!client_); | 166 DCHECK(!client_); |
| 158 client_ = client; | 167 client_ = client; |
| 159 bool success = true; | |
| 160 | 168 |
| 161 if (context_provider_.get()) { | 169 if (context_provider_) { |
| 162 success = context_provider_->BindToCurrentThread(); | 170 if (!context_provider_->BindToCurrentThread()) |
| 163 if (success) { | 171 return false; |
| 164 context_provider_->SetLostContextCallback(base::Bind( | 172 |
| 165 &OutputSurface::DidLoseOutputSurface, base::Unretained(this))); | 173 context_provider_->SetLostContextCallback(base::Bind( |
| 166 } | 174 &OutputSurface::DidLoseOutputSurface, base::Unretained(this))); |
| 167 } | 175 } |
| 168 | 176 |
| 169 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). | 177 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). |
| 170 // Don't register a dump provider in these cases. | 178 // Don't register a dump provider in these cases. |
| 171 // TODO(ericrk): Get this working in Android Webview. crbug.com/517156 | 179 // TODO(ericrk): Get this working in Android Webview. crbug.com/517156 |
| 172 if (base::ThreadTaskRunnerHandle::IsSet()) { | 180 if (base::ThreadTaskRunnerHandle::IsSet()) { |
| 173 // Now that we are on the context thread, register a dump provider with this | 181 // Now that we are on the context thread, register a dump provider with this |
| 174 // thread's task runner. This will overwrite any previous dump provider | 182 // thread's task runner. This will overwrite any previous dump provider |
| 175 // registered. | 183 // registered. |
| 176 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 184 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| 177 this, "OutputSurface", base::ThreadTaskRunnerHandle::Get()); | 185 this, "OutputSurface", base::ThreadTaskRunnerHandle::Get()); |
| 178 } | 186 } |
| 179 | 187 return true; |
| 180 if (!success) | |
| 181 DetachFromClient(); | |
| 182 return success; | |
| 183 } | |
| 184 | |
| 185 void OutputSurface::DetachFromClient() { | |
| 186 DetachFromClientInternal(); | |
| 187 } | |
| 188 | |
| 189 void OutputSurface::EnsureBackbuffer() { | |
| 190 if (software_device_) | |
| 191 software_device_->EnsureBackbuffer(); | |
| 192 } | |
| 193 | |
| 194 void OutputSurface::DiscardBackbuffer() { | |
| 195 if (context_provider_.get()) | |
| 196 context_provider_->ContextGL()->DiscardBackbufferCHROMIUM(); | |
| 197 if (software_device_) | |
| 198 software_device_->DiscardBackbuffer(); | |
| 199 } | 188 } |
| 200 | 189 |
| 201 void OutputSurface::Reshape(const gfx::Size& size, | 190 void OutputSurface::Reshape(const gfx::Size& size, |
| 202 float scale_factor, | 191 float scale_factor, |
| 203 const gfx::ColorSpace& color_space, | 192 const gfx::ColorSpace& color_space, |
| 204 bool has_alpha) { | 193 bool has_alpha) { |
| 205 device_color_space_ = color_space; | 194 device_color_space_ = color_space; |
| 206 if (size == surface_size_ && scale_factor == device_scale_factor_ && | 195 if (size == surface_size_ && scale_factor == device_scale_factor_ && |
| 207 has_alpha == has_alpha_) | 196 has_alpha == has_alpha_) |
| 208 return; | 197 return; |
| 209 | 198 |
| 210 surface_size_ = size; | 199 surface_size_ = size; |
| 211 device_scale_factor_ = scale_factor; | 200 device_scale_factor_ = scale_factor; |
| 212 has_alpha_ = has_alpha; | 201 has_alpha_ = has_alpha; |
| 213 if (context_provider_.get()) { | 202 if (context_provider_.get()) { |
| 214 context_provider_->ContextGL()->ResizeCHROMIUM(size.width(), size.height(), | 203 context_provider_->ContextGL()->ResizeCHROMIUM(size.width(), size.height(), |
| 215 scale_factor, has_alpha); | 204 scale_factor, has_alpha); |
| 216 } | 205 } |
| 217 if (software_device_) | 206 if (software_device_) |
| 218 software_device_->Resize(size, scale_factor); | 207 software_device_->Resize(size, scale_factor); |
| 219 } | 208 } |
| 220 | 209 |
| 221 void OutputSurface::BindFramebuffer() { | |
| 222 DCHECK(context_provider_.get()); | |
| 223 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0); | |
| 224 } | |
| 225 | |
| 226 void OutputSurface::PostSwapBuffersComplete() { | 210 void OutputSurface::PostSwapBuffersComplete() { |
| 227 base::ThreadTaskRunnerHandle::Get()->PostTask( | 211 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 228 FROM_HERE, base::Bind(&OutputSurface::OnSwapBuffersComplete, | 212 FROM_HERE, base::Bind(&OutputSurface::OnSwapBuffersComplete, |
| 229 weak_ptr_factory_.GetWeakPtr())); | 213 weak_ptr_factory_.GetWeakPtr())); |
| 230 } | 214 } |
| 231 | 215 |
| 232 // We don't post tasks bound to the client directly since they might run | 216 // We don't post tasks bound to the client directly since they might run |
| 233 // after the OutputSurface has been destroyed. | 217 // after the OutputSurface has been destroyed. |
| 234 void OutputSurface::OnSwapBuffersComplete() { | 218 void OutputSurface::OnSwapBuffersComplete() { |
| 235 client_->DidSwapBuffersComplete(); | 219 client_->DidSwapBuffersComplete(); |
| 236 } | 220 } |
| 237 | 221 |
| 238 void OutputSurface::DidReceiveTextureInUseResponses( | |
| 239 const gpu::TextureInUseResponses& responses) { | |
| 240 client_->DidReceiveTextureInUseResponses(responses); | |
| 241 } | |
| 242 | |
| 243 OverlayCandidateValidator* OutputSurface::GetOverlayCandidateValidator() const { | |
| 244 return nullptr; | |
| 245 } | |
| 246 | |
| 247 bool OutputSurface::IsDisplayedAsOverlayPlane() const { | |
| 248 return false; | |
| 249 } | |
| 250 | |
| 251 unsigned OutputSurface::GetOverlayTextureId() const { | |
| 252 return 0; | |
| 253 } | |
| 254 | |
| 255 bool OutputSurface::SurfaceIsSuspendForRecycle() const { | |
| 256 return false; | |
| 257 } | |
| 258 | |
| 259 bool OutputSurface::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, | 222 bool OutputSurface::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, |
| 260 base::trace_event::ProcessMemoryDump* pmd) { | 223 base::trace_event::ProcessMemoryDump* pmd) { |
| 261 if (auto* context_provider = this->context_provider()) { | 224 if (auto* context_provider = this->context_provider()) { |
| 262 // No need to lock, main context provider is not shared. | 225 // No need to lock, main context provider is not shared. |
| 263 if (auto* gr_context = context_provider->GrContext()) { | 226 if (auto* gr_context = context_provider->GrContext()) { |
| 264 SkiaGpuTraceMemoryDump trace_memory_dump( | 227 SkiaGpuTraceMemoryDump trace_memory_dump( |
| 265 pmd, context_provider->ContextSupport()->ShareGroupTracingGUID()); | 228 pmd, context_provider->ContextSupport()->ShareGroupTracingGUID()); |
| 266 gr_context->dumpMemoryStatistics(&trace_memory_dump); | 229 gr_context->dumpMemoryStatistics(&trace_memory_dump); |
| 267 } | 230 } |
| 268 } | 231 } |
| 269 return true; | 232 return true; |
| 270 } | 233 } |
| 271 | 234 |
| 272 void OutputSurface::DetachFromClientInternal() { | |
| 273 DCHECK(client_thread_checker_.CalledOnValidThread()); | |
| 274 DCHECK(client_); | |
| 275 | |
| 276 // Unregister any dump provider. Safe to call (no-op) if we have not yet | |
| 277 // registered. | |
| 278 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | |
| 279 this); | |
| 280 | |
| 281 if (context_provider_.get()) { | |
| 282 context_provider_->SetLostContextCallback( | |
| 283 ContextProvider::LostContextCallback()); | |
| 284 } | |
| 285 context_provider_ = nullptr; | |
| 286 client_ = nullptr; | |
| 287 weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 288 } | |
| 289 | |
| 290 void OutputSurface::DidLoseOutputSurface() { | 235 void OutputSurface::DidLoseOutputSurface() { |
| 291 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); | 236 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); |
| 292 client_->DidLoseOutputSurface(); | 237 client_->DidLoseOutputSurface(); |
| 293 } | 238 } |
| 294 | 239 |
| 295 } // namespace cc | 240 } // namespace cc |
| OLD | NEW |