// 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 "components/mus/ws/server_window_surface.h" #include "cc/output/compositor_frame.h" #include "cc/quads/shared_quad_state.h" #include "cc/quads/surface_draw_quad.h" #include "components/mus/surfaces/surfaces_state.h" #include "components/mus/ws/server_window.h" #include "components/mus/ws/server_window_delegate.h" #include "components/mus/ws/server_window_surface_manager.h" #include "mojo/converters/geometry/geometry_type_converters.h" #include "mojo/converters/surfaces/surfaces_type_converters.h" namespace mus { namespace ws { namespace { void CallCallback(const mojo::Closure& callback, cc::SurfaceDrawStatus status) { callback.Run(); } } // namespace ServerWindowSurface::ServerWindowSurface( ServerWindowSurfaceManager* manager, mojom::SurfaceType surface_type, mojo::InterfaceRequest request, mojom::SurfaceClientPtr client) : manager_(manager), surface_type_(surface_type), surface_id_(manager->GenerateId()), surface_factory_(manager_->window() ->delegate() ->GetSurfacesState() ->manager(), this), client_(client.Pass()), binding_(this, request.Pass()) { surface_factory_.Create(surface_id_); } ServerWindowSurface::~ServerWindowSurface() { // SurfaceFactory's destructor will attempt to return resources which will // call back into here and access |client_| so we should destroy // |surface_factory_|'s resources early on. surface_factory_.DestroyAll(); } void ServerWindowSurface::SubmitCompositorFrame( mojom::CompositorFramePtr frame, const SubmitCompositorFrameCallback& callback) { gfx::Size frame_size = frame->passes[0]->output_rect.To().size(); if (!surface_id_.is_null()) { // If the size of the CompostiorFrame has changed then destroy the existing // Surface and create a new one of the appropriate size. if (frame_size != last_submitted_frame_size_) { surface_factory_.Destroy(surface_id_); surface_id_ = manager_->GenerateId(); surface_factory_.Create(surface_id_); } } surface_factory_.SubmitCompositorFrame(surface_id_, ConvertCompositorFrame(frame), base::Bind(&CallCallback, callback)); window()->delegate()->GetSurfacesState()->scheduler()->SetNeedsDraw(); window()->delegate()->OnScheduleWindowPaint(window()); last_submitted_frame_size_ = frame_size; } ServerWindow* ServerWindowSurface::window() { return manager_->window(); } scoped_ptr ServerWindowSurface::ConvertCompositorFrame( const mojom::CompositorFramePtr& input) { referenced_window_ids_.clear(); return ConvertToCompositorFrame(input, this); } bool ServerWindowSurface::ConvertSurfaceDrawQuad( const mojom::QuadPtr& input, const mojom::CompositorFrameMetadataPtr& metadata, cc::SharedQuadState* sqs, cc::RenderPass* render_pass) { Id id = static_cast( input->surface_quad_state->surface.To().id); WindowId other_window_id = WindowIdFromTransportId(id); ServerWindow* other_window = window()->GetChildWindow(other_window_id); if (!other_window) return false; referenced_window_ids_.insert(other_window_id); ServerWindowSurface* default_surface = other_window->GetOrCreateSurfaceManager()->GetDefaultSurface(); ServerWindowSurface* underlay_surface = other_window->GetOrCreateSurfaceManager()->GetUnderlaySurface(); if (!default_surface && !underlay_surface) return true; cc::SurfaceDrawQuad* surface_quad = render_pass->CreateAndAppendDrawQuad(); if (default_surface) { surface_quad->SetAll(sqs, input->rect.To(), input->opaque_rect.To(), input->visible_rect.To(), input->needs_blending, default_surface->id()); } if (underlay_surface) { cc::SurfaceDrawQuad* underlay_quad = render_pass->CreateAndAppendDrawQuad(); underlay_quad->SetAll(sqs, input->rect.To(), input->opaque_rect.To(), input->visible_rect.To(), input->needs_blending, underlay_surface->id()); } return true; } void ServerWindowSurface::ReturnResources( const cc::ReturnedResourceArray& resources) { if (!client_) return; client_->ReturnResources( mojo::Array::From(resources)); } void ServerWindowSurface::SetBeginFrameSource( cc::SurfaceId surface_id, cc::BeginFrameSource* begin_frame_source) { // TODO(tansell): Implement this. } } // namespace ws } // namespace mus