Home | History | Annotate | Download | only in aura
      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
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/aura/browser_compositor_output_surface.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/command_line.h"
      9 #include "base/location.h"
     10 #include "base/message_loop/message_loop_proxy.h"
     11 #include "base/strings/string_number_conversions.h"
     12 #include "cc/output/compositor_frame.h"
     13 #include "content/browser/aura/reflector_impl.h"
     14 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
     15 #include "ui/compositor/compositor.h"
     16 #include "ui/compositor/compositor_switches.h"
     17 
     18 namespace content {
     19 
     20 BrowserCompositorOutputSurface::BrowserCompositorOutputSurface(
     21     scoped_ptr<WebKit::WebGraphicsContext3D> context,
     22     int surface_id,
     23     IDMap<BrowserCompositorOutputSurface>* output_surface_map,
     24     base::MessageLoopProxy* compositor_message_loop,
     25     base::WeakPtr<ui::Compositor> compositor)
     26     : OutputSurface(context.Pass()),
     27       surface_id_(surface_id),
     28       output_surface_map_(output_surface_map),
     29       compositor_message_loop_(compositor_message_loop),
     30       compositor_(compositor) {
     31   CommandLine* command_line = CommandLine::ForCurrentProcess();
     32   if (command_line->HasSwitch(switches::kUIMaxFramesPending)) {
     33     std::string string_value = command_line->GetSwitchValueASCII(
     34         switches::kUIMaxFramesPending);
     35     int int_value;
     36     if (base::StringToInt(string_value, &int_value))
     37       capabilities_.max_frames_pending = int_value;
     38     else
     39       LOG(ERROR) << "Trouble parsing --" << switches::kUIMaxFramesPending;
     40   }
     41   capabilities_.adjust_deadline_for_parent = false;
     42   DetachFromThread();
     43 }
     44 
     45 BrowserCompositorOutputSurface::~BrowserCompositorOutputSurface() {
     46   DCHECK(CalledOnValidThread());
     47   if (!HasClient())
     48     return;
     49   output_surface_map_->Remove(surface_id_);
     50 }
     51 
     52 bool BrowserCompositorOutputSurface::BindToClient(
     53     cc::OutputSurfaceClient* client) {
     54   DCHECK(CalledOnValidThread());
     55 
     56   if (!OutputSurface::BindToClient(client))
     57     return false;
     58 
     59   output_surface_map_->AddWithID(this, surface_id_);
     60   return true;
     61 }
     62 
     63 void BrowserCompositorOutputSurface::Reshape(gfx::Size size,
     64                                              float scale_factor) {
     65   OutputSurface::Reshape(size, scale_factor);
     66   if (reflector_.get())
     67     reflector_->OnReshape(size);
     68 }
     69 
     70 void BrowserCompositorOutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
     71   DCHECK(frame->gl_frame_data);
     72 
     73   WebGraphicsContext3DCommandBufferImpl* command_buffer =
     74       static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d());
     75   CommandBufferProxyImpl* command_buffer_proxy =
     76       command_buffer->GetCommandBufferProxy();
     77   DCHECK(command_buffer_proxy);
     78   context3d()->shallowFlushCHROMIUM();
     79   command_buffer_proxy->SetLatencyInfo(frame->metadata.latency_info);
     80 
     81   if (reflector_.get()) {
     82     if (frame->gl_frame_data->sub_buffer_rect ==
     83         gfx::Rect(frame->gl_frame_data->size))
     84       reflector_->OnSwapBuffers();
     85     else
     86       reflector_->OnPostSubBuffer(frame->gl_frame_data->sub_buffer_rect);
     87   }
     88 
     89   OutputSurface::SwapBuffers(frame);
     90 }
     91 
     92 void BrowserCompositorOutputSurface::OnUpdateVSyncParameters(
     93     base::TimeTicks timebase,
     94     base::TimeDelta interval) {
     95   DCHECK(CalledOnValidThread());
     96   DCHECK(HasClient());
     97   OnVSyncParametersChanged(timebase, interval);
     98   compositor_message_loop_->PostTask(
     99       FROM_HERE,
    100       base::Bind(&ui::Compositor::OnUpdateVSyncParameters,
    101                  compositor_, timebase, interval));
    102 }
    103 
    104 void BrowserCompositorOutputSurface::SetReflector(ReflectorImpl* reflector) {
    105   reflector_ = reflector;
    106 }
    107 
    108 }  // namespace content
    109