diff options
Diffstat (limited to 'chromium/cc/output/output_surface.cc')
-rw-r--r-- | chromium/cc/output/output_surface.cc | 238 |
1 files changed, 55 insertions, 183 deletions
diff --git a/chromium/cc/output/output_surface.cc b/chromium/cc/output/output_surface.cc index 5bad7ec89b7..46096d2e309 100644 --- a/chromium/cc/output/output_surface.cc +++ b/chromium/cc/output/output_surface.cc @@ -24,7 +24,6 @@ #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" #include "ui/gfx/frame_time.h" @@ -45,194 +44,57 @@ const double kGpuLatencyEstimationPercentile = 100.0; namespace cc { OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) - : context_provider_(context_provider), + : client_(NULL), + context_provider_(context_provider), device_scale_factor_(-1), - max_frames_pending_(0), - pending_swap_buffers_(0), - needs_begin_impl_frame_(false), - client_ready_for_begin_impl_frame_(true), - client_(NULL), - check_for_retroactive_begin_impl_frame_pending_(false), external_stencil_test_enabled_(false), weak_ptr_factory_(this), - gpu_latency_history_(kGpuLatencyHistorySize) {} + gpu_latency_history_(kGpuLatencyHistorySize) { +} OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) - : software_device_(software_device.Pass()), + : client_(NULL), + software_device_(software_device.Pass()), device_scale_factor_(-1), - max_frames_pending_(0), - pending_swap_buffers_(0), - needs_begin_impl_frame_(false), - client_ready_for_begin_impl_frame_(true), - client_(NULL), - check_for_retroactive_begin_impl_frame_pending_(false), external_stencil_test_enabled_(false), weak_ptr_factory_(this), - gpu_latency_history_(kGpuLatencyHistorySize) {} + gpu_latency_history_(kGpuLatencyHistorySize) { +} OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider, scoped_ptr<SoftwareOutputDevice> software_device) - : context_provider_(context_provider), + : client_(NULL), + context_provider_(context_provider), software_device_(software_device.Pass()), device_scale_factor_(-1), - max_frames_pending_(0), - pending_swap_buffers_(0), - needs_begin_impl_frame_(false), - client_ready_for_begin_impl_frame_(true), - client_(NULL), - check_for_retroactive_begin_impl_frame_pending_(false), external_stencil_test_enabled_(false), weak_ptr_factory_(this), - gpu_latency_history_(kGpuLatencyHistorySize) {} - -void OutputSurface::InitializeBeginImplFrameEmulation( - base::SingleThreadTaskRunner* task_runner, - bool throttle_frame_production, - base::TimeDelta interval) { - if (throttle_frame_production) { - scoped_refptr<DelayBasedTimeSource> time_source; - if (gfx::FrameTime::TimestampsAreHighRes()) - time_source = DelayBasedTimeSourceHighRes::Create(interval, task_runner); - else - time_source = DelayBasedTimeSource::Create(interval, task_runner); - frame_rate_controller_.reset(new FrameRateController(time_source)); - } else { - frame_rate_controller_.reset(new FrameRateController(task_runner)); - } - - frame_rate_controller_->SetClient(this); - frame_rate_controller_->SetMaxSwapsPending(max_frames_pending_); - frame_rate_controller_->SetDeadlineAdjustment( - capabilities_.adjust_deadline_for_parent ? - BeginFrameArgs::DefaultDeadlineAdjustment() : base::TimeDelta()); - - // The new frame rate controller will consume the swap acks of the old - // frame rate controller, so we set that expectation up here. - for (int i = 0; i < pending_swap_buffers_; i++) - frame_rate_controller_->DidSwapBuffers(); -} - -void OutputSurface::SetMaxFramesPending(int max_frames_pending) { - if (frame_rate_controller_) - frame_rate_controller_->SetMaxSwapsPending(max_frames_pending); - max_frames_pending_ = max_frames_pending; -} - -void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase, - base::TimeDelta interval) { - TRACE_EVENT2("cc", "OutputSurface::OnVSyncParametersChanged", - "timebase", (timebase - base::TimeTicks()).InSecondsF(), - "interval", interval.InSecondsF()); - if (frame_rate_controller_) - frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); + gpu_latency_history_(kGpuLatencyHistorySize) { } -void OutputSurface::FrameRateControllerTick(bool throttled, - const BeginFrameArgs& args) { - DCHECK(frame_rate_controller_); - if (throttled) - skipped_begin_impl_frame_args_ = args; - else - BeginImplFrame(args); +void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) { + TRACE_EVENT2("cc", + "OutputSurface::CommitVSyncParameters", + "timebase", + (timebase - base::TimeTicks()).InSecondsF(), + "interval", + interval.InSecondsF()); + client_->CommitVSyncParameters(timebase, interval); } // Forwarded to OutputSurfaceClient -void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) { +void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect"); client_->SetNeedsRedrawRect(damage_rect); } -void OutputSurface::SetNeedsBeginImplFrame(bool enable) { - TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginImplFrame", "enable", enable); - needs_begin_impl_frame_ = enable; - client_ready_for_begin_impl_frame_ = true; - if (frame_rate_controller_) { - BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable); - if (skipped.IsValid()) - skipped_begin_impl_frame_args_ = skipped; - } - if (needs_begin_impl_frame_) - PostCheckForRetroactiveBeginImplFrame(); -} - -void OutputSurface::BeginImplFrame(const BeginFrameArgs& args) { - TRACE_EVENT2("cc", "OutputSurface::BeginImplFrame", - "client_ready_for_begin_impl_frame_", - client_ready_for_begin_impl_frame_, - "pending_swap_buffers_", pending_swap_buffers_); - if (!needs_begin_impl_frame_ || !client_ready_for_begin_impl_frame_ || - (pending_swap_buffers_ >= max_frames_pending_ && - max_frames_pending_ > 0)) { - skipped_begin_impl_frame_args_ = args; - } else { - client_ready_for_begin_impl_frame_ = false; - client_->BeginImplFrame(args); - // args might be an alias for skipped_begin_impl_frame_args_. - // Do not reset it before calling BeginImplFrame! - skipped_begin_impl_frame_args_ = BeginFrameArgs(); - } -} - -base::TimeTicks OutputSurface::RetroactiveBeginImplFrameDeadline() { - // TODO(brianderson): Remove the alternative deadline once we have better - // deadline estimations. - base::TimeTicks alternative_deadline = - skipped_begin_impl_frame_args_.frame_time + - BeginFrameArgs::DefaultRetroactiveBeginFramePeriod(); - return std::max(skipped_begin_impl_frame_args_.deadline, - alternative_deadline); -} - -void OutputSurface::PostCheckForRetroactiveBeginImplFrame() { - if (!skipped_begin_impl_frame_args_.IsValid() || - check_for_retroactive_begin_impl_frame_pending_) - return; - - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&OutputSurface::CheckForRetroactiveBeginImplFrame, - weak_ptr_factory_.GetWeakPtr())); - check_for_retroactive_begin_impl_frame_pending_ = true; -} - -void OutputSurface::CheckForRetroactiveBeginImplFrame() { - TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginImplFrame"); - check_for_retroactive_begin_impl_frame_pending_ = false; - if (gfx::FrameTime::Now() < RetroactiveBeginImplFrameDeadline()) - BeginImplFrame(skipped_begin_impl_frame_args_); -} - -void OutputSurface::DidSwapBuffers() { - pending_swap_buffers_++; - TRACE_EVENT1("cc", "OutputSurface::DidSwapBuffers", - "pending_swap_buffers_", pending_swap_buffers_); - client_->DidSwapBuffers(); - if (frame_rate_controller_) - frame_rate_controller_->DidSwapBuffers(); - PostCheckForRetroactiveBeginImplFrame(); -} - -void OutputSurface::OnSwapBuffersComplete() { - pending_swap_buffers_--; - TRACE_EVENT1("cc", "OutputSurface::OnSwapBuffersComplete", - "pending_swap_buffers_", pending_swap_buffers_); - client_->OnSwapBuffersComplete(); - if (frame_rate_controller_) - frame_rate_controller_->DidSwapBuffersComplete(); - PostCheckForRetroactiveBeginImplFrame(); -} - void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) { client_->ReclaimResources(ack); } void OutputSurface::DidLoseOutputSurface() { TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); - client_ready_for_begin_impl_frame_ = true; - pending_swap_buffers_ = 0; - skipped_begin_impl_frame_args_ = BeginFrameArgs(); - if (frame_rate_controller_) - frame_rate_controller_->SetActive(false); pending_gpu_latency_query_ids_.clear(); available_gpu_latency_query_ids_.clear(); client_->DidLoseOutputSurface(); @@ -243,16 +105,14 @@ void OutputSurface::SetExternalStencilTest(bool enabled) { } void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform, - gfx::Rect viewport, - gfx::Rect clip, + const gfx::Rect& viewport, + const gfx::Rect& clip, bool valid_for_tile_management) { client_->SetExternalDrawConstraints( transform, viewport, clip, valid_for_tile_management); } OutputSurface::~OutputSurface() { - if (frame_rate_controller_) - frame_rate_controller_->SetActive(false); ResetContext3d(); } @@ -280,8 +140,7 @@ bool OutputSurface::BindToClient(OutputSurfaceClient* client) { } bool OutputSurface::InitializeAndSetContext3d( - scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> offscreen_context_provider) { + scoped_refptr<ContextProvider> context_provider) { DCHECK(!context_provider_); DCHECK(context_provider); DCHECK(client_); @@ -290,8 +149,8 @@ bool OutputSurface::InitializeAndSetContext3d( if (context_provider->BindToCurrentThread()) { context_provider_ = context_provider; SetUpContext3d(); - if (client_->DeferredInitialize(offscreen_context_provider)) - success = true; + client_->DeferredInitialize(); + success = true; } if (!success) @@ -304,7 +163,7 @@ void OutputSurface::ReleaseGL() { DCHECK(client_); DCHECK(context_provider_); client_->ReleaseGL(); - ResetContext3d(); + DCHECK(!context_provider_); } void OutputSurface::SetUpContext3d() { @@ -322,17 +181,23 @@ void OutputSurface::SetUpContext3d() { base::Unretained(this))); } +void OutputSurface::ReleaseContextProvider() { + DCHECK(client_); + DCHECK(context_provider_); + ResetContext3d(); +} + void OutputSurface::ResetContext3d() { if (context_provider_.get()) { while (!pending_gpu_latency_query_ids_.empty()) { unsigned query_id = pending_gpu_latency_query_ids_.front(); pending_gpu_latency_query_ids_.pop_front(); - context_provider_->Context3d()->deleteQueryEXT(query_id); + context_provider_->ContextGL()->DeleteQueriesEXT(1, &query_id); } while (!available_gpu_latency_query_ids_.empty()) { unsigned query_id = available_gpu_latency_query_ids_.front(); available_gpu_latency_query_ids_.pop_front(); - context_provider_->Context3d()->deleteQueryEXT(query_id); + context_provider_->ContextGL()->DeleteQueriesEXT(1, &query_id); } context_provider_->SetLostContextCallback( ContextProvider::LostContextCallback()); @@ -356,18 +221,18 @@ void OutputSurface::DiscardBackbuffer() { software_device_->DiscardBackbuffer(); } -void OutputSurface::Reshape(gfx::Size size, float scale_factor) { +void OutputSurface::Reshape(const gfx::Size& size, float scale_factor) { if (size == surface_size_ && scale_factor == device_scale_factor_) return; surface_size_ = size; device_scale_factor_ = scale_factor; if (context_provider_) { - context_provider_->Context3d()->reshapeWithScaleFactor( + context_provider_->ContextGL()->ResizeCHROMIUM( size.width(), size.height(), scale_factor); } if (software_device_) - software_device_->Resize(size); + software_device_->Resize(size, scale_factor); } gfx::Size OutputSurface::SurfaceSize() const { @@ -376,13 +241,13 @@ gfx::Size OutputSurface::SurfaceSize() const { void OutputSurface::BindFramebuffer() { DCHECK(context_provider_); - context_provider_->Context3d()->bindFramebuffer(GL_FRAMEBUFFER, 0); + context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0); } void OutputSurface::SwapBuffers(CompositorFrame* frame) { if (frame->software_frame_data) { PostSwapBuffersComplete(); - DidSwapBuffers(); + client_->DidSwapBuffers(); return; } @@ -398,7 +263,7 @@ void OutputSurface::SwapBuffers(CompositorFrame* frame) { frame->gl_frame_data->sub_buffer_rect); } - DidSwapBuffers(); + client_->DidSwapBuffers(); } base::TimeDelta OutputSurface::GpuLatencyEstimate() { @@ -409,8 +274,8 @@ base::TimeDelta OutputSurface::GpuLatencyEstimate() { } void OutputSurface::UpdateAndMeasureGpuLatency() { - return; // http://crbug.com/306690 tracks re-enabling latency queries. - + // http://crbug.com/306690 tracks re-enabling latency queries. +#if 0 // We only care about GPU latency for surfaces that do not have a parent // compositor, since surfaces that do have a parent compositor can use // mailboxes or delegated rendering to send frames to their parent without @@ -421,13 +286,13 @@ void OutputSurface::UpdateAndMeasureGpuLatency() { while (pending_gpu_latency_query_ids_.size()) { unsigned query_id = pending_gpu_latency_query_ids_.front(); unsigned query_complete = 1; - context_provider_->Context3d()->getQueryObjectuivEXT( + context_provider_->ContextGL()->GetQueryObjectuivEXT( query_id, GL_QUERY_RESULT_AVAILABLE_EXT, &query_complete); if (!query_complete) break; unsigned value = 0; - context_provider_->Context3d()->getQueryObjectuivEXT( + context_provider_->ContextGL()->GetQueryObjectuivEXT( query_id, GL_QUERY_RESULT_EXT, &value); pending_gpu_latency_query_ids_.pop_front(); available_gpu_latency_query_ids_.push_back(query_id); @@ -464,13 +329,14 @@ void OutputSurface::UpdateAndMeasureGpuLatency() { gpu_latency_query_id = available_gpu_latency_query_ids_.front(); available_gpu_latency_query_ids_.pop_front(); } else { - gpu_latency_query_id = context_provider_->Context3d()->createQueryEXT(); + context_provider_->ContextGL()->GenQueriesEXT(1, &gpu_latency_query_id); } - context_provider_->Context3d()->beginQueryEXT(GL_LATENCY_QUERY_CHROMIUM, + context_provider_->ContextGL()->BeginQueryEXT(GL_LATENCY_QUERY_CHROMIUM, gpu_latency_query_id); - context_provider_->Context3d()->endQueryEXT(GL_LATENCY_QUERY_CHROMIUM); + context_provider_->ContextGL()->EndQueryEXT(GL_LATENCY_QUERY_CHROMIUM); pending_gpu_latency_query_ids_.push_back(gpu_latency_query_id); +#endif } void OutputSurface::PostSwapBuffersComplete() { @@ -480,6 +346,12 @@ void OutputSurface::PostSwapBuffersComplete() { weak_ptr_factory_.GetWeakPtr())); } +// We don't post tasks bound to the client directly since they might run +// after the OutputSurface has been destroyed. +void OutputSurface::OnSwapBuffersComplete() { + client_->DidSwapBuffersComplete(); +} + void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy", "bytes_limit_when_visible", policy.bytes_limit_when_visible); |