Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: ui/gfx/compositor/compositor.cc

Issue 10365007: ui: Move compositor/ directory out of gfx/, up to ui/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix DEPS Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gfx/compositor/compositor.h ('k') | ui/gfx/compositor/compositor.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "ui/gfx/compositor/compositor.h"
6
7 #include "base/command_line.h"
8 #include "base/threading/thread_restrictions.h"
9 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositor.h"
10 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoin t.h"
11 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "third_party/skia/include/images/SkImageEncoder.h"
15 #include "ui/gfx/compositor/compositor_observer.h"
16 #include "ui/gfx/compositor/compositor_switches.h"
17 #include "ui/gfx/compositor/layer.h"
18 #include "ui/gfx/compositor/test_web_graphics_context_3d.h"
19 #include "ui/gfx/gl/gl_context.h"
20 #include "ui/gfx/gl/gl_implementation.h"
21 #include "ui/gfx/gl/gl_surface.h"
22 #include "webkit/glue/webthread_impl.h"
23 #include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
24
25 namespace {
26
27 const double kDefaultRefreshRate = 60.0;
28 const double kTestRefreshRate = 100.0;
29
30 webkit_glue::WebThreadImpl* g_compositor_thread = NULL;
31
32 bool test_compositor_enabled = false;
33
34 ui::ContextFactory* g_context_factory = NULL;
35
36 } // anonymous namespace
37
38 namespace ui {
39
40 // static
41 ContextFactory* ContextFactory::GetInstance() {
42 // We leak the shared resources so that we don't race with
43 // the tear down of the gl_bindings.
44 if (!g_context_factory) {
45 DVLOG(1) << "Using DefaultSharedResource";
46 scoped_ptr<DefaultContextFactory> instance(
47 new DefaultContextFactory());
48 if (instance->Initialize())
49 g_context_factory = instance.release();
50 }
51 return g_context_factory;
52 }
53
54 // static
55 void ContextFactory::SetInstance(ContextFactory* instance) {
56 g_context_factory = instance;
57 }
58
59 DefaultContextFactory::DefaultContextFactory() {
60 }
61
62 DefaultContextFactory::~DefaultContextFactory() {
63 }
64
65 bool DefaultContextFactory::Initialize() {
66 // The following line of code exists soley to disable IO restrictions
67 // on this thread long enough to perform the GL bindings.
68 // TODO(wjmaclean) Remove this when GL initialisation cleaned up.
69 base::ThreadRestrictions::ScopedAllowIO allow_io;
70 if (!gfx::GLSurface::InitializeOneOff() ||
71 gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
72 LOG(ERROR) << "Could not load the GL bindings";
73 return false;
74 }
75 return true;
76 }
77
78 WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateContext(
79 Compositor* compositor) {
80 return CreateContextCommon(compositor, false);
81 }
82
83 WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateOffscreenContext(
84 Compositor* compositor) {
85 return CreateContextCommon(compositor, true);
86 }
87
88 void DefaultContextFactory::RemoveCompositor(Compositor* compositor) {
89 }
90
91 WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateContextCommon(
92 Compositor* compositor,
93 bool offscreen) {
94 WebKit::WebGraphicsContext3D::Attributes attrs;
95 attrs.shareResources = true;
96 WebKit::WebGraphicsContext3D* context =
97 offscreen ?
98 webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWebView(
99 attrs, false) :
100 webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow(
101 attrs, compositor->widget(), share_group_.get());
102 CommandLine* command_line = CommandLine::ForCurrentProcess();
103 if (!command_line->HasSwitch(switches::kDisableUIVsync)) {
104 context->makeContextCurrent();
105 gfx::GLContext* gl_context = gfx::GLContext::GetCurrent();
106 gl_context->SetSwapInterval(1);
107 gl_context->ReleaseCurrent(NULL);
108 }
109 return context;
110 }
111
112 Texture::Texture(bool flipped, const gfx::Size& size)
113 : texture_id_(0),
114 flipped_(flipped),
115 size_(size) {
116 }
117
118 Texture::~Texture() {
119 }
120
121 Compositor::Compositor(CompositorDelegate* delegate,
122 gfx::AcceleratedWidget widget,
123 const gfx::Size& size)
124 : delegate_(delegate),
125 size_(size),
126 root_layer_(NULL),
127 widget_(widget),
128 root_web_layer_(WebKit::WebLayer::create()),
129 swap_posted_(false) {
130 WebKit::WebLayerTreeView::Settings settings;
131 CommandLine* command_line = CommandLine::ForCurrentProcess();
132 settings.showFPSCounter =
133 command_line->HasSwitch(switches::kUIShowFPSCounter);
134 settings.showPlatformLayerTree =
135 command_line->HasSwitch(switches::kUIShowLayerTree);
136 settings.refreshRate = test_compositor_enabled ?
137 kTestRefreshRate : kDefaultRefreshRate;
138 settings.partialSwapEnabled =
139 command_line->HasSwitch(switches::kUIEnablePartialSwap);
140 settings.perTilePainting =
141 command_line->HasSwitch(switches::kUIEnablePerTilePainting);
142
143 host_.initialize(this, root_web_layer_, settings);
144 root_web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f));
145 WidgetSizeChanged(size_);
146 }
147
148 Compositor::~Compositor() {
149 // There's a cycle between |root_web_layer_| and |host_|, which results in
150 // leaking and/or crashing. Explicitly set the root layer to NULL so the cycle
151 // is broken.
152 host_.setRootLayer(NULL);
153 if (root_layer_)
154 root_layer_->SetCompositor(NULL);
155 if (!test_compositor_enabled)
156 ContextFactory::GetInstance()->RemoveCompositor(this);
157 }
158
159 void Compositor::Initialize(bool use_thread) {
160 if (use_thread)
161 g_compositor_thread = new webkit_glue::WebThreadImpl("Browser Compositor");
162 WebKit::WebCompositor::initialize(g_compositor_thread);
163 }
164
165 void Compositor::Terminate() {
166 WebKit::WebCompositor::shutdown();
167 if (g_compositor_thread) {
168 delete g_compositor_thread;
169 g_compositor_thread = NULL;
170 }
171 }
172
173 void Compositor::ScheduleDraw() {
174 if (g_compositor_thread) {
175 // TODO(nduca): Temporary while compositor calls
176 // compositeImmediately() directly.
177 layout();
178 host_.composite();
179 } else {
180 delegate_->ScheduleDraw();
181 }
182 }
183
184 void Compositor::SetRootLayer(Layer* root_layer) {
185 if (root_layer_ == root_layer)
186 return;
187 if (root_layer_)
188 root_layer_->SetCompositor(NULL);
189 root_layer_ = root_layer;
190 if (root_layer_ && !root_layer_->GetCompositor())
191 root_layer_->SetCompositor(this);
192 root_web_layer_.removeAllChildren();
193 if (root_layer_)
194 root_web_layer_.addChild(root_layer_->web_layer());
195 }
196
197 void Compositor::Draw(bool force_clear) {
198 if (!root_layer_)
199 return;
200
201 // TODO(nduca): Temporary while compositor calls
202 // compositeImmediately() directly.
203 layout();
204 host_.composite();
205 if (!g_compositor_thread && !swap_posted_)
206 NotifyEnd();
207 }
208
209 void Compositor::ScheduleFullDraw() {
210 host_.setNeedsRedraw();
211 }
212
213 bool Compositor::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
214 if (bounds.right() > size().width() || bounds.bottom() > size().height())
215 return false;
216 // Convert to OpenGL coordinates.
217 gfx::Point new_origin(bounds.x(),
218 size().height() - bounds.height() - bounds.y());
219
220 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
221 bounds.width(), bounds.height());
222 bitmap->allocPixels();
223 SkAutoLockPixels lock_image(*bitmap);
224 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
225 if (host_.compositeAndReadback(pixels,
226 gfx::Rect(new_origin, bounds.size()))) {
227 SwizzleRGBAToBGRAAndFlip(pixels, bounds.size());
228 return true;
229 }
230 return false;
231 }
232
233 void Compositor::WidgetSizeChanged(const gfx::Size& size) {
234 if (size.IsEmpty())
235 return;
236 size_ = size;
237 host_.setViewportSize(size_);
238 root_web_layer_.setBounds(size_);
239 }
240
241 void Compositor::AddObserver(CompositorObserver* observer) {
242 observer_list_.AddObserver(observer);
243 }
244
245 void Compositor::RemoveObserver(CompositorObserver* observer) {
246 observer_list_.RemoveObserver(observer);
247 }
248
249 bool Compositor::HasObserver(CompositorObserver* observer) {
250 return observer_list_.HasObserver(observer);
251 }
252
253 void Compositor::OnSwapBuffersPosted() {
254 swap_posted_ = true;
255 }
256
257 void Compositor::OnSwapBuffersComplete() {
258 DCHECK(swap_posted_);
259 swap_posted_ = false;
260 NotifyEnd();
261 }
262
263 void Compositor::OnSwapBuffersAborted() {
264 if (swap_posted_) {
265 swap_posted_ = false;
266 NotifyEnd();
267 }
268 }
269
270 void Compositor::updateAnimations(double frameBeginTime) {
271 }
272
273 void Compositor::layout() {
274 if (root_layer_)
275 root_layer_->SendDamagedRects();
276 }
277
278 void Compositor::applyScrollAndScale(const WebKit::WebSize& scrollDelta,
279 float scaleFactor) {
280 }
281
282 WebKit::WebGraphicsContext3D* Compositor::createContext3D() {
283 if (test_compositor_enabled) {
284 ui::TestWebGraphicsContext3D* test_context =
285 new ui::TestWebGraphicsContext3D();
286 test_context->Initialize();
287 return test_context;
288 } else {
289 return ContextFactory::GetInstance()->CreateContext(this);
290 }
291 }
292
293 void Compositor::didRebindGraphicsContext(bool success) {
294 }
295
296 void Compositor::didCommitAndDrawFrame() {
297 FOR_EACH_OBSERVER(CompositorObserver,
298 observer_list_,
299 OnCompositingStarted(this));
300 }
301
302 void Compositor::didCompleteSwapBuffers() {
303 NotifyEnd();
304 }
305
306 void Compositor::scheduleComposite() {
307 ScheduleDraw();
308 }
309
310 void Compositor::SwizzleRGBAToBGRAAndFlip(unsigned char* pixels,
311 const gfx::Size& image_size) {
312 // Swizzle from RGBA to BGRA
313 size_t bitmap_size = 4 * image_size.width() * image_size.height();
314 for(size_t i = 0; i < bitmap_size; i += 4)
315 std::swap(pixels[i], pixels[i + 2]);
316
317 // Vertical flip to transform from GL co-ords
318 size_t row_size = 4 * image_size.width();
319 scoped_array<unsigned char> tmp_row(new unsigned char[row_size]);
320 for(int row = 0; row < image_size.height() / 2; row++) {
321 memcpy(tmp_row.get(),
322 &pixels[row * row_size],
323 row_size);
324 memcpy(&pixels[row * row_size],
325 &pixels[bitmap_size - (row + 1) * row_size],
326 row_size);
327 memcpy(&pixels[bitmap_size - (row + 1) * row_size],
328 tmp_row.get(),
329 row_size);
330 }
331 }
332
333 void Compositor::NotifyEnd() {
334 FOR_EACH_OBSERVER(CompositorObserver,
335 observer_list_,
336 OnCompositingEnded(this));
337 }
338
339 COMPOSITOR_EXPORT void SetupTestCompositor() {
340 if (!CommandLine::ForCurrentProcess()->HasSwitch(
341 switches::kDisableTestCompositor)) {
342 test_compositor_enabled = true;
343 }
344 }
345
346 COMPOSITOR_EXPORT void DisableTestCompositor() {
347 test_compositor_enabled = false;
348 }
349
350 COMPOSITOR_EXPORT bool IsTestCompositorEnabled() {
351 return test_compositor_enabled;
352 }
353
354 } // namespace ui
OLDNEW
« no previous file with comments | « ui/gfx/compositor/compositor.h ('k') | ui/gfx/compositor/compositor.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698