Index: mojo/services/native_viewport/native_viewport_impl.cc |
diff --git a/mojo/services/native_viewport/native_viewport_impl.cc b/mojo/services/native_viewport/native_viewport_impl.cc |
index 0b871dc33845e9bc335f7ccecb4715d447585f1d..f34f4aa3d92fe570cb213291106d51b2e8296d05 100644 |
--- a/mojo/services/native_viewport/native_viewport_impl.cc |
+++ b/mojo/services/native_viewport/native_viewport_impl.cc |
@@ -12,6 +12,7 @@ |
#include "mojo/public/cpp/application/interface_factory.h" |
#include "mojo/services/public/cpp/geometry/geometry_type_converters.h" |
#include "mojo/services/public/cpp/input_events/input_events_type_converters.h" |
+#include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h" |
#include "ui/events/event.h" |
namespace mojo { |
@@ -25,10 +26,14 @@ bool IsRateLimitedEventType(ui::Event* event) { |
} // namespace |
-NativeViewportImpl::NativeViewportImpl() |
- : widget_(gfx::kNullAcceleratedWidget), |
- waiting_for_event_ack_(false), |
- weak_factory_(this) {} |
+NativeViewportImpl::NativeViewportImpl(SurfacesServicePtr surfaces_service, |
+ GpuPtr gpu_service) |
+ : surfaces_service_(surfaces_service.Pass()), |
+ gpu_service_(gpu_service.Pass()), |
+ widget_id_(0u), |
+ waiting_for_event_ack_(false), |
+ weak_factory_(this) { |
+} |
NativeViewportImpl::~NativeViewportImpl() { |
// Destroy the NativeViewport early on as it may call us back during |
@@ -59,15 +64,109 @@ void NativeViewportImpl::SetBounds(RectPtr bounds) { |
platform_viewport_->SetBounds(bounds.To<gfx::Rect>()); |
} |
+void NativeViewportImpl::SubmittedFrame(SurfaceIdPtr surface_id) { |
+ if (child_surface_id_.is_null()) { |
+ // If this is the first indication that the client will use surfaces, |
+ // initialize that system. |
+ // TODO(jamesr): When everything is converted to surfaces initialize this |
+ // eagerly. |
+ surfaces_service_->CreateSurfaceConnection( |
+ base::Bind(&NativeViewportImpl::OnSurfaceConnectionCreated, |
+ base::Unretained(this))); |
sky
2014/08/26 23:16:32
Is it possible for 'this' to be deleted before the
jamesr
2014/08/26 23:17:22
Oh whoops, it is. I'll bind to a weak ptr
|
+ } |
+ child_surface_id_ = surface_id.To<cc::SurfaceId>(); |
+ SubmitFrame(); |
+} |
+ |
void NativeViewportImpl::OnBoundsChanged(const gfx::Rect& bounds) { |
+ if (bounds == bounds_) |
+ return; |
+ bounds_ = bounds; |
client()->OnBoundsChanged(Rect::From(bounds)); |
+ if (!surface_id_.is_null()) |
+ surface_->DestroySurface(SurfaceId::From(surface_id_)); |
+ if (!surface_id_allocator_) |
+ return; |
+ surface_id_ = surface_id_allocator_->GenerateId(); |
+ surface_->CreateSurface(SurfaceId::From(surface_id_), |
+ Size::From(bounds_.size())); |
+ SubmitFrame(); |
} |
void NativeViewportImpl::OnAcceleratedWidgetAvailable( |
gfx::AcceleratedWidget widget) { |
- widget_ = widget; |
- uintptr_t widget_ptr = bit_cast<uintptr_t>(widget); |
- client()->OnCreated(static_cast<uint64_t>(widget_ptr)); |
+ widget_id_ = static_cast<uint64_t>(bit_cast<uintptr_t>(widget)); |
+ // TODO(jamesr): Remove once everything is converted to surfaces. |
+ client()->OnCreated(widget_id_); |
+ if (surface_id_allocator_) |
+ CreateViewportBoundSurface(); |
+} |
+ |
+void NativeViewportImpl::CreateViewportBoundSurface() { |
+ DCHECK(surface_id_.is_null()); |
+ CommandBufferPtr cb; |
+ gpu_service_->CreateOnscreenGLES2Context( |
+ widget_id_, Size::From(bounds_.size()), Get(&cb)); |
+ |
+ surface_id_ = surface_id_allocator_->GenerateId(); |
+ surface_->CreateGLES2BoundSurface( |
+ cb.Pass(), SurfaceId::From(surface_id_), Size::From(bounds_.size())); |
+ |
+ SubmitFrame(); |
+} |
+ |
+void NativeViewportImpl::ReturnResources(Array<ReturnedResourcePtr> resources) { |
+ // We never submit resources so we should never get any back. |
+ DCHECK_EQ(0u, resources.size()); |
+} |
+void NativeViewportImpl::OnSurfaceConnectionCreated(SurfacePtr surface, |
+ uint32_t id_namespace) { |
+ surface_ = surface.Pass(); |
+ surface_.set_client(this); |
+ surface_id_allocator_.reset(new cc::SurfaceIdAllocator(id_namespace)); |
+ if (widget_id_) |
+ CreateViewportBoundSurface(); |
+} |
+ |
+void NativeViewportImpl::SubmitFrame() { |
+ if (child_surface_id_.is_null() || surface_id_.is_null()) |
+ return; |
+ |
jamesr
2014/08/26 23:05:50
the rest of this function is an unfortunately larg
|
+ SurfaceQuadStatePtr surface_quad_state = SurfaceQuadState::New(); |
+ surface_quad_state->surface = SurfaceId::From(child_surface_id_); |
+ |
+ QuadPtr surface_quad = Quad::New(); |
+ surface_quad->material = Material::MATERIAL_SURFACE_CONTENT; |
+ surface_quad->rect = Rect::From(bounds_); |
+ surface_quad->opaque_rect = Rect::From(bounds_); |
+ surface_quad->visible_rect = Rect::From(bounds_); |
+ surface_quad->needs_blending = true; |
+ surface_quad->shared_quad_state_index = 0; |
+ surface_quad->surface_quad_state = surface_quad_state.Pass(); |
+ |
+ SharedQuadStatePtr sqs = SharedQuadState::New(); |
+ sqs->content_to_target_transform = Transform::From(gfx::Transform()); |
+ sqs->content_bounds = Size::From(bounds_.size()); |
+ sqs->visible_content_rect = Rect::From(bounds_); |
+ sqs->clip_rect = Rect::From(bounds_); |
+ sqs->is_clipped = false; |
+ sqs->opacity = 1.0f; |
+ sqs->blend_mode = SkXfermode::SK_XFERMODE_kSrcOver_Mode; |
+ sqs->sorting_context_id = 1; |
+ |
+ PassPtr pass = Pass::New(); |
+ pass->id = 1; |
+ pass->output_rect = Rect::From(bounds_); |
+ pass->damage_rect = Rect::From(bounds_); |
+ pass->transform_to_root_target = Transform::From(gfx::Transform()); |
+ pass->has_transparent_background = false; |
+ pass->quads.push_back(surface_quad.Pass()); |
+ pass->shared_quad_states.push_back(sqs.Pass()); |
+ |
+ FramePtr frame = Frame::New(); |
+ frame->passes.push_back(pass.Pass()); |
+ frame->resources.resize(0u); |
+ surface_->SubmitFrame(SurfaceId::From(surface_id_), frame.Pass()); |
} |
bool NativeViewportImpl::OnEvent(ui::Event* ui_event) { |