| Index: mojo/services/surfaces/display_impl.cc
 | 
| diff --git a/mojo/services/surfaces/display_impl.cc b/mojo/services/surfaces/display_impl.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..3fff760d2935513523b4109101ea9030e5add42d
 | 
| --- /dev/null
 | 
| +++ b/mojo/services/surfaces/display_impl.cc
 | 
| @@ -0,0 +1,137 @@
 | 
| +// Copyright 2015 The Chromium Authors. All rights reserved.
 | 
| +// Use of this source code is governed by a BSD-style license that can be
 | 
| +// found in the LICENSE file.
 | 
| +
 | 
| +#include "mojo/services/surfaces/display_impl.h"
 | 
| +
 | 
| +#include "cc/output/compositor_frame.h"
 | 
| +#include "cc/surfaces/display.h"
 | 
| +#include "mojo/converters/geometry/geometry_type_converters.h"
 | 
| +#include "mojo/converters/surfaces/surfaces_type_converters.h"
 | 
| +#include "mojo/services/surfaces/context_provider_mojo.h"
 | 
| +#include "mojo/services/surfaces/surfaces_output_surface.h"
 | 
| +#include "mojo/services/surfaces/surfaces_scheduler.h"
 | 
| +
 | 
| +namespace surfaces {
 | 
| +namespace {
 | 
| +void CallCallback(const mojo::Closure& callback, cc::SurfaceDrawStatus status) {
 | 
| +  callback.Run();
 | 
| +}
 | 
| +}
 | 
| +
 | 
| +DisplayImpl::DisplayImpl(cc::SurfaceManager* manager,
 | 
| +                         cc::SurfaceId cc_id,
 | 
| +                         SurfacesScheduler* scheduler,
 | 
| +                         mojo::ContextProviderPtr context_provider,
 | 
| +                         mojo::ResourceReturnerPtr returner,
 | 
| +                         mojo::InterfaceRequest<mojo::Display> display_request)
 | 
| +    : manager_(manager),
 | 
| +      factory_(manager, this),
 | 
| +      cc_id_(cc_id),
 | 
| +      scheduler_(scheduler),
 | 
| +      context_provider_(context_provider.Pass()),
 | 
| +      returner_(returner.Pass()),
 | 
| +      viewport_param_binding_(this),
 | 
| +      display_binding_(this, display_request.Pass()) {
 | 
| +  mojo::ViewportParameterListenerPtr viewport_parameter_listener;
 | 
| +  viewport_param_binding_.Bind(GetProxy(&viewport_parameter_listener));
 | 
| +  context_provider_->Create(
 | 
| +      viewport_parameter_listener.Pass(),
 | 
| +      base::Bind(&DisplayImpl::OnContextCreated, base::Unretained(this)));
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::OnContextCreated(mojo::CommandBufferPtr gles2_client) {
 | 
| +  DCHECK(!display_);
 | 
| +
 | 
| +  cc::RendererSettings settings;
 | 
| +  display_.reset(new cc::Display(this, manager_, nullptr, nullptr, settings));
 | 
| +  scheduler_->AddDisplay(display_.get());
 | 
| +  display_->Initialize(make_scoped_ptr(new mojo::DirectOutputSurface(
 | 
| +      new mojo::ContextProviderMojo(gles2_client.PassMessagePipe()))));
 | 
| +
 | 
| +  factory_.Create(cc_id_);
 | 
| +  display_->SetSurfaceId(cc_id_, 1.f);
 | 
| +  if (pending_frame_)
 | 
| +    Draw();
 | 
| +}
 | 
| +
 | 
| +DisplayImpl::~DisplayImpl() {
 | 
| +  if (display_) {
 | 
| +    factory_.Destroy(cc_id_);
 | 
| +    scheduler_->RemoveDisplay(display_.get());
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::SubmitFrame(mojo::FramePtr frame,
 | 
| +                              const SubmitFrameCallback& callback) {
 | 
| +  DCHECK(pending_callback_.is_null());
 | 
| +  pending_frame_ = frame.Pass();
 | 
| +  pending_callback_ = callback;
 | 
| +  if (display_)
 | 
| +    Draw();
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::Draw() {
 | 
| +  gfx::Size frame_size =
 | 
| +      pending_frame_->passes[0]->output_rect.To<gfx::Rect>().size();
 | 
| +  display_->Resize(frame_size);
 | 
| +  factory_.SubmitFrame(cc_id_,
 | 
| +                       pending_frame_.To<scoped_ptr<cc::CompositorFrame>>(),
 | 
| +                       base::Bind(&CallCallback, pending_callback_));
 | 
| +  scheduler_->SetNeedsDraw();
 | 
| +  pending_callback_.reset();
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::DisplayDamaged() {
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::DidSwapBuffers() {
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::DidSwapBuffersComplete() {
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::CommitVSyncParameters(base::TimeTicks timebase,
 | 
| +                                        base::TimeDelta interval) {
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::OutputSurfaceLost() {
 | 
| +  // If our OutputSurface is lost we can't draw until we get a new one. For now,
 | 
| +  // destroy the display and create a new one when our ContextProvider provides
 | 
| +  // a new one.
 | 
| +  // TODO: This is more violent than necessary - we could simply remove this
 | 
| +  // display from the scheduler's set and pass a new context in to the
 | 
| +  // OutputSurface. It should be able to reinitialize properly.
 | 
| +  scheduler_->RemoveDisplay(display_.get());
 | 
| +  display_.reset();
 | 
| +  factory_.Destroy(cc_id_);
 | 
| +  viewport_param_binding_.Close();
 | 
| +  mojo::ViewportParameterListenerPtr viewport_parameter_listener;
 | 
| +  viewport_param_binding_.Bind(GetProxy(&viewport_parameter_listener));
 | 
| +  context_provider_->Create(
 | 
| +      viewport_parameter_listener.Pass(),
 | 
| +      base::Bind(&DisplayImpl::OnContextCreated, base::Unretained(this)));
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) {
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::OnVSyncParametersUpdated(int64_t timebase, int64_t interval) {
 | 
| +  scheduler_->OnVSyncParametersUpdated(
 | 
| +      base::TimeTicks::FromInternalValue(timebase),
 | 
| +      base::TimeDelta::FromInternalValue(interval));
 | 
| +}
 | 
| +
 | 
| +void DisplayImpl::ReturnResources(const cc::ReturnedResourceArray& resources) {
 | 
| +  if (resources.empty())
 | 
| +    return;
 | 
| +  DCHECK(returner_);
 | 
| +
 | 
| +  mojo::Array<mojo::ReturnedResourcePtr> ret(resources.size());
 | 
| +  for (size_t i = 0; i < resources.size(); ++i) {
 | 
| +    ret[i] = mojo::ReturnedResource::From(resources[i]);
 | 
| +  }
 | 
| +  returner_->ReturnResources(ret.Pass());
 | 
| +}
 | 
| +
 | 
| +}  // namespace surfaces
 | 
| 
 |