IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / browser / aura / reflector_impl.cc
blob6d8e89df70c2bb3e17a137cfe7416f38531fab3f
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.
5 #include "content/browser/aura/reflector_impl.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "content/browser/aura/browser_compositor_output_surface.h"
10 #include "content/common/gpu/client/gl_helper.h"
11 #include "ui/compositor/layer.h"
13 namespace content {
15 ReflectorImpl::ReflectorImpl(
16 ui::Compositor* mirrored_compositor,
17 ui::Layer* mirroring_layer,
18 IDMap<BrowserCompositorOutputSurface>* output_surface_map,
19 int surface_id)
20 : texture_id_(0),
21 texture_size_(mirrored_compositor->size()),
22 output_surface_map_(output_surface_map),
23 mirrored_compositor_(mirrored_compositor),
24 mirroring_compositor_(mirroring_layer->GetCompositor()),
25 mirroring_layer_(mirroring_layer),
26 impl_message_loop_(ui::Compositor::GetCompositorMessageLoop()),
27 main_message_loop_(base::MessageLoopProxy::current()),
28 surface_id_(surface_id) {
29 CreateSharedTexture();
30 impl_message_loop_->PostTask(
31 FROM_HERE,
32 base::Bind(&ReflectorImpl::InitOnImplThread, this));
35 void ReflectorImpl::InitOnImplThread() {
36 // Ignore if the reflector was shutdown before
37 // initialized, or it's already initialized.
38 if (!output_surface_map_ || gl_helper_.get())
39 return;
41 BrowserCompositorOutputSurface* source_surface =
42 output_surface_map_->Lookup(surface_id_);
43 // Skip if the source surface isn't ready yet. This will be
44 // initiailze when the source surface becomes ready.
45 if (!source_surface)
46 return;
48 AttachToOutputSurface(source_surface);
49 gl_helper_->CopyTextureFullImage(texture_id_, texture_size_);
50 // The shared texture doesn't have the data, so invokes full redraw
51 // now.
52 main_message_loop_->PostTask(
53 FROM_HERE,
54 base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
55 scoped_refptr<ReflectorImpl>(this)));
58 void ReflectorImpl::OnSourceSurfaceReady(int surface_id) {
59 DCHECK_EQ(surface_id_, surface_id);
60 InitOnImplThread();
63 void ReflectorImpl::Shutdown() {
64 mirroring_compositor_ = NULL;
65 mirroring_layer_ = NULL;
66 shared_texture_ = NULL;
67 impl_message_loop_->PostTask(
68 FROM_HERE,
69 base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
72 void ReflectorImpl::ShutdownOnImplThread() {
73 BrowserCompositorOutputSurface* output_surface =
74 output_surface_map_->Lookup(surface_id_);
75 if (output_surface)
76 output_surface->SetReflector(NULL);
77 output_surface_map_ = NULL;
78 gl_helper_.reset();
79 // The instance must be deleted on main thread.
80 main_message_loop_->PostTask(
81 FROM_HERE,
82 base::Bind(&ReflectorImpl::DeleteOnMainThread,
83 scoped_refptr<ReflectorImpl>(this)));
86 // This must be called on ImplThread, or before the surface is passed to
87 // ImplThread.
88 void ReflectorImpl::AttachToOutputSurface(
89 BrowserCompositorOutputSurface* output_surface) {
90 gl_helper_.reset(
91 new GLHelper(output_surface->context_provider()->ContextGL(),
92 output_surface->context_provider()->ContextSupport()));
93 output_surface->SetReflector(this);
96 void ReflectorImpl::OnMirroringCompositorResized() {
97 mirroring_compositor_->ScheduleFullRedraw();
100 void ReflectorImpl::OnLostResources() {
101 shared_texture_ = NULL;
102 mirroring_layer_->SetShowPaintedContent();
105 void ReflectorImpl::OnReshape(gfx::Size size) {
106 if (texture_size_ == size)
107 return;
108 texture_size_ = size;
109 DCHECK(texture_id_);
110 gl_helper_->ResizeTexture(texture_id_, size);
111 main_message_loop_->PostTask(
112 FROM_HERE,
113 base::Bind(&ReflectorImpl::UpdateTextureSizeOnMainThread,
114 this->AsWeakPtr(),
115 texture_size_));
118 void ReflectorImpl::OnSwapBuffers() {
119 DCHECK(texture_id_);
120 gl_helper_->CopyTextureFullImage(texture_id_, texture_size_);
121 main_message_loop_->PostTask(
122 FROM_HERE,
123 base::Bind(&ReflectorImpl::FullRedrawOnMainThread,
124 this->AsWeakPtr(),
125 texture_size_));
128 void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) {
129 DCHECK(texture_id_);
130 gl_helper_->CopyTextureSubImage(texture_id_, rect);
131 main_message_loop_->PostTask(
132 FROM_HERE,
133 base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
134 this->AsWeakPtr(),
135 texture_size_,
136 rect));
139 void ReflectorImpl::CreateSharedTexture() {
140 texture_id_ =
141 ImageTransportFactory::GetInstance()->GetGLHelper()->CreateTexture();
142 shared_texture_ =
143 ImageTransportFactory::GetInstance()->CreateOwnedTexture(
144 texture_size_, 1.0f, texture_id_);
145 mirroring_layer_->SetExternalTexture(shared_texture_.get());
148 ReflectorImpl::~ReflectorImpl() {
149 // Make sure the reflector is deleted on main thread.
150 DCHECK_EQ(main_message_loop_.get(),
151 base::MessageLoopProxy::current().get());
154 void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) {
155 if (!mirroring_layer_)
156 return;
157 mirroring_layer_->SetBounds(gfx::Rect(size));
160 void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) {
161 if (!mirroring_compositor_)
162 return;
163 UpdateTextureSizeOnMainThread(size);
164 mirroring_compositor_->ScheduleFullRedraw();
167 void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size,
168 gfx::Rect rect) {
169 if (!mirroring_compositor_)
170 return;
171 UpdateTextureSizeOnMainThread(size);
172 // Flip the coordinates to compositor's one.
173 int y = size.height() - rect.y() - rect.height();
174 gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height());
175 mirroring_layer_->SchedulePaint(new_rect);
178 void ReflectorImpl::FullRedrawContentOnMainThread() {
179 mirrored_compositor_->ScheduleFullRedraw();
182 } // namespace content