15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// found in the LICENSE file.
4558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/reflector_impl.h"
6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
7558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/bind.h"
8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/location.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/browser_compositor_output_surface.h"
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/compositor/owned_mailbox.h"
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/client/gl_helper.h"
12558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/compositor/layer.h"
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace content {
15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
16558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochReflectorImpl::ReflectorImpl(
17558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ui::Compositor* mirrored_compositor,
18558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ui::Layer* mirroring_layer,
19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    IDMap<BrowserCompositorOutputSurface>* output_surface_map,
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoopProxy* compositor_thread_loop,
21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    int surface_id)
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : impl_unsafe_(output_surface_map),
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      main_unsafe_(mirrored_compositor, mirroring_layer),
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      impl_message_loop_(compositor_thread_loop),
25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      main_message_loop_(base::MessageLoopProxy::current()),
26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      surface_id_(surface_id) {
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MainThreadData& main = GetMain();
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mailbox = new OwnedMailbox(helper);
30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  impl_message_loop_->PostTask(
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      FROM_HERE,
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::Bind(
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          &ReflectorImpl::InitOnImplThread, this, main.mailbox->holder()));
34558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
35558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochReflectorImpl::MainThreadData::MainThreadData(
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ui::Compositor* mirrored_compositor,
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ui::Layer* mirroring_layer)
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : needs_set_mailbox(true),
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      mirrored_compositor(mirrored_compositor),
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      mirroring_layer(mirroring_layer) {}
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochReflectorImpl::MainThreadData::~MainThreadData() {}
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochReflectorImpl::ImplThreadData::ImplThreadData(
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    IDMap<BrowserCompositorOutputSurface>* output_surface_map)
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : output_surface_map(output_surface_map),
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      output_surface(NULL),
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      texture_id(0) {}
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochReflectorImpl::ImplThreadData::~ImplThreadData() {}
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochReflectorImpl::ImplThreadData& ReflectorImpl::GetImpl() {
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(impl_message_loop_->BelongsToCurrentThread());
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return impl_unsafe_;
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochReflectorImpl::MainThreadData& ReflectorImpl::GetMain() {
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(main_message_loop_->BelongsToCurrentThread());
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return main_unsafe_;
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ReflectorImpl::InitOnImplThread(const gpu::MailboxHolder& mailbox_holder) {
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ImplThreadData& impl = GetImpl();
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Ignore if the reflector was shutdown before
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // initialized, or it's already initialized.
67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!impl.output_surface_map || impl.gl_helper.get())
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.mailbox_holder = mailbox_holder;
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  BrowserCompositorOutputSurface* source_surface =
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      impl.output_surface_map->Lookup(surface_id_);
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Skip if the source surface isn't ready yet. This will be
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // initialized when the source surface becomes ready.
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!source_surface)
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  AttachToOutputSurfaceOnImplThread(impl.mailbox_holder, source_surface);
80558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
81558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ReflectorImpl::OnSourceSurfaceReady(
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    BrowserCompositorOutputSurface* source_surface) {
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ImplThreadData& impl = GetImpl();
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  AttachToOutputSurfaceOnImplThread(impl.mailbox_holder, source_surface);
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::Shutdown() {
89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MainThreadData& main = GetMain();
90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mailbox = NULL;
91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mirroring_layer->SetShowPaintedContent();
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mirroring_layer = NULL;
93558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  impl_message_loop_->PostTask(
94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      FROM_HERE, base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ReflectorImpl::DetachFromOutputSurface() {
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ImplThreadData& impl = GetImpl();
99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(impl.output_surface);
100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.output_surface->SetReflector(NULL);
101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(impl.texture_id);
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.gl_helper->DeleteTexture(impl.texture_id);
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.texture_id = 0;
104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.gl_helper.reset();
105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.output_surface = NULL;
106558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
107558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
108558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::ShutdownOnImplThread() {
109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ImplThreadData& impl = GetImpl();
110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (impl.output_surface)
111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    DetachFromOutputSurface();
112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.output_surface_map = NULL;
113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // The instance must be deleted on main thread.
114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main_message_loop_->PostTask(FROM_HERE,
115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                               base::Bind(&ReflectorImpl::DeleteOnMainThread,
116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                          scoped_refptr<ReflectorImpl>(this)));
117558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
118558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ReflectorImpl::ReattachToOutputSurfaceFromMainThread(
120558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    BrowserCompositorOutputSurface* output_surface) {
121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MainThreadData& main = GetMain();
122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mailbox = new OwnedMailbox(helper);
124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.needs_set_mailbox = true;
125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mirroring_layer->SetShowPaintedContent();
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  impl_message_loop_->PostTask(
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&ReflectorImpl::AttachToOutputSurfaceOnImplThread,
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 this,
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 main.mailbox->holder(),
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 output_surface));
132558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
133558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
134558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::OnMirroringCompositorResized() {
135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MainThreadData& main = GetMain();
136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mirroring_layer->SchedulePaint(main.mirroring_layer->bounds());
137558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
138558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
139558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::OnSwapBuffers() {
140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ImplThreadData& impl = GetImpl();
141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  gfx::Size size = impl.output_surface->SurfaceSize();
142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (impl.texture_id) {
143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    impl.gl_helper->CopyTextureFullImage(impl.texture_id, size);
144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    impl.gl_helper->Flush();
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
146558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  main_message_loop_->PostTask(
147558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      FROM_HERE,
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::Bind(
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          &ReflectorImpl::FullRedrawOnMainThread, this->AsWeakPtr(), size));
150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
152558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) {
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ImplThreadData& impl = GetImpl();
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (impl.texture_id) {
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    impl.gl_helper->CopyTextureSubImage(impl.texture_id, rect);
156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    impl.gl_helper->Flush();
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
158558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  main_message_loop_->PostTask(
159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      FROM_HERE,
160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
161558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                 this->AsWeakPtr(),
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 impl.output_surface->SurfaceSize(),
163558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                 rect));
164558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
165558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
166558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochReflectorImpl::~ReflectorImpl() {
167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Make sure the reflector is deleted on main thread.
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK_EQ(main_message_loop_.get(), base::MessageLoopProxy::current().get());
169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox,
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                           unsigned int sync_point,
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                           bool is_lost) {
174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  mailbox->UpdateSyncPoint(sync_point);
175558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ReflectorImpl::AttachToOutputSurfaceOnImplThread(
178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const gpu::MailboxHolder& mailbox_holder,
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    BrowserCompositorOutputSurface* output_surface) {
180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ImplThreadData& impl = GetImpl();
181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (output_surface == impl.output_surface)
182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return;
183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (impl.output_surface)
184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    DetachFromOutputSurface();
185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.output_surface = output_surface;
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  output_surface->context_provider()->BindToCurrentThread();
187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.gl_helper.reset(
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new GLHelper(output_surface->context_provider()->ContextGL(),
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   output_surface->context_provider()->ContextSupport()));
190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.texture_id = impl.gl_helper->ConsumeMailboxToTexture(
191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      mailbox_holder.mailbox, mailbox_holder.sync_point);
192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.gl_helper->ResizeTexture(impl.texture_id, output_surface->SurfaceSize());
193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  impl.gl_helper->Flush();
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  output_surface->SetReflector(this);
195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // The texture doesn't have the data, so invokes full redraw now.
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  main_message_loop_->PostTask(
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 scoped_refptr<ReflectorImpl>(this)));
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
202558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) {
203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MainThreadData& main = GetMain();
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!main.mirroring_layer || !main.mailbox.get() ||
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      main.mailbox->mailbox().IsZero())
206558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (main.needs_set_mailbox) {
208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    main.mirroring_layer->SetTextureMailbox(
209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        cc::TextureMailbox(main.mailbox->holder()),
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        cc::SingleReleaseCallback::Create(
211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            base::Bind(ReleaseMailbox, main.mailbox)),
212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        size);
213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    main.needs_set_mailbox = false;
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  } else {
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    main.mirroring_layer->SetTextureSize(size);
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mirroring_layer->SetBounds(gfx::Rect(size));
218558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
219558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
220558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) {
221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MainThreadData& main = GetMain();
222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!main.mirroring_layer)
223558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
224558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  UpdateTextureSizeOnMainThread(size);
225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mirroring_layer->SchedulePaint(main.mirroring_layer->bounds());
226558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
227558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size,
229558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                gfx::Rect rect) {
230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MainThreadData& main = GetMain();
231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!main.mirroring_layer)
232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
233558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  UpdateTextureSizeOnMainThread(size);
234558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Flip the coordinates to compositor's one.
235558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  int y = size.height() - rect.y() - rect.height();
236558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height());
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mirroring_layer->SchedulePaint(new_rect);
238558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
239558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
240558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid ReflectorImpl::FullRedrawContentOnMainThread() {
241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  MainThreadData& main = GetMain();
242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  main.mirrored_compositor->ScheduleFullRedraw();
243558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
245558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}  // namespace content
246