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

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

Issue 9297041: Merge Compositor and CompositorCC (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 10 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/compositor/compositor.h" 5 #include "ui/gfx/compositor/compositor.h"
6 6
7 #include "base/command_line.h"
8 #include "third_party/skia/include/images/SkImageEncoder.h"
9 #include "third_party/skia/include/core/SkBitmap.h"
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositor.h"
11 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoin t.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
7 #include "ui/gfx/compositor/compositor_observer.h" 14 #include "ui/gfx/compositor/compositor_observer.h"
15 #include "ui/gfx/compositor/compositor_switches.h"
16 #include "ui/gfx/compositor/test_web_graphics_context_3d.h"
8 #include "ui/gfx/compositor/layer.h" 17 #include "ui/gfx/compositor/layer.h"
18 #include "ui/gfx/gl/gl_context.h"
19 #include "ui/gfx/gl/gl_surface.h"
20 #include "ui/gfx/gl/gl_implementation.h"
21 #include "ui/gfx/gl/scoped_make_current.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 } // anonymous namespace
9 35
10 namespace ui { 36 namespace ui {
11 37
12 TextureDrawParams::TextureDrawParams() 38 SharedResources::SharedResources() : initialized_(false) {
13 : blend(false),
14 has_valid_alpha_channel(false),
15 opacity(1.0f),
16 vertically_flipped(false) {
17 } 39 }
18 40
19 Compositor::Compositor(CompositorDelegate* delegate, const gfx::Size& size) 41
42 SharedResources::~SharedResources() {
43 }
44
45 // static
46 SharedResources* SharedResources::GetInstance() {
47 // We use LeakySingletonTraits so that we don't race with
48 // the tear down of the gl_bindings.
49 SharedResources* instance = Singleton<SharedResources,
50 LeakySingletonTraits<SharedResources> >::get();
51 if (instance->Initialize()) {
52 return instance;
53 } else {
54 instance->Destroy();
55 return NULL;
56 }
57 }
58
59 bool SharedResources::Initialize() {
60 if (initialized_)
61 return true;
62
63 {
64 // The following line of code exists soley to disable IO restrictions
65 // on this thread long enough to perform the GL bindings.
66 // TODO(wjmaclean) Remove this when GL initialisation cleaned up.
67 base::ThreadRestrictions::ScopedAllowIO allow_io;
68 if (!gfx::GLSurface::InitializeOneOff() ||
69 gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
70 LOG(ERROR) << "Could not load the GL bindings";
71 return false;
72 }
73 }
74
75 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1));
76 if (!surface_.get()) {
77 LOG(ERROR) << "Unable to create offscreen GL surface.";
78 return false;
79 }
80
81 context_ = gfx::GLContext::CreateGLContext(
82 NULL, surface_.get(), gfx::PreferIntegratedGpu);
83 if (!context_.get()) {
84 LOG(ERROR) << "Unable to create GL context.";
85 return false;
86 }
87
88 initialized_ = true;
89 return true;
90 }
91
92 void SharedResources::Destroy() {
93 context_ = NULL;
94 surface_ = NULL;
95
96 initialized_ = false;
97 }
98
99 gfx::ScopedMakeCurrent* SharedResources::GetScopedMakeCurrent() {
100 DCHECK(initialized_);
101 if (initialized_)
102 return new gfx::ScopedMakeCurrent(context_.get(), surface_.get());
103 else
104 return NULL;
105 }
106
107 void* SharedResources::GetDisplay() {
108 return surface_->GetDisplay();
109 }
110
111 gfx::GLShareGroup* SharedResources::GetShareGroup() {
112 DCHECK(initialized_);
113 return context_->share_group();
114 }
115
116 Texture::Texture()
117 : texture_id_(0),
118 flipped_(false) {
119 }
120
121 Texture::~Texture() {
122 }
123
124 Compositor::Compositor(CompositorDelegate* delegate,
125 gfx::AcceleratedWidget widget,
126 const gfx::Size& size)
20 : delegate_(delegate), 127 : delegate_(delegate),
21 size_(size), 128 size_(size),
22 root_layer_(NULL) { 129 root_layer_(NULL),
130 widget_(widget),
131 root_web_layer_(WebKit::WebLayer::create()) {
132 WebKit::WebLayerTreeView::Settings settings;
133 CommandLine* command_line = CommandLine::ForCurrentProcess();
134 settings.showFPSCounter =
135 command_line->HasSwitch(switches::kUIShowFPSCounter);
136 settings.showPlatformLayerTree =
137 command_line->HasSwitch(switches::kUIShowLayerTree);
138 settings.refreshRate = test_compositor_enabled ?
139 kTestRefreshRate : kDefaultRefreshRate;
140 settings.partialSwapEnabled =
141 command_line->HasSwitch(switches::kUIEnablePartialSwap);
142
143 host_ = WebKit::WebLayerTreeView::create(this, root_web_layer_, settings);
144 root_web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f));
145 WidgetSizeChanged(size_);
23 } 146 }
24 147
25 Compositor::~Compositor() { 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);
26 if (root_layer_) 153 if (root_layer_)
27 root_layer_->SetCompositor(NULL); 154 root_layer_->SetCompositor(NULL);
28 } 155 }
29 156
157 void Compositor::Initialize(bool use_thread) {
158 if (use_thread)
159 g_compositor_thread = new webkit_glue::WebThreadImpl("Browser Compositor");
160 WebKit::WebCompositor::initialize(g_compositor_thread);
161 }
162
163 void Compositor::Terminate() {
164 WebKit::WebCompositor::shutdown();
165 if (g_compositor_thread) {
166 delete g_compositor_thread;
167 g_compositor_thread = NULL;
168 }
169 }
170
30 void Compositor::ScheduleDraw() { 171 void Compositor::ScheduleDraw() {
31 delegate_->ScheduleDraw(); 172 if (g_compositor_thread)
173 host_.composite();
174 else
175 delegate_->ScheduleDraw();
32 } 176 }
33 177
34 void Compositor::SetRootLayer(Layer* root_layer) { 178 void Compositor::SetRootLayer(Layer* root_layer) {
35 if (root_layer_ == root_layer) 179 if (root_layer_ == root_layer)
36 return; 180 return;
37 if (root_layer_) 181 if (root_layer_)
38 root_layer_->SetCompositor(NULL); 182 root_layer_->SetCompositor(NULL);
39 root_layer_ = root_layer; 183 root_layer_ = root_layer;
40 if (root_layer_ && !root_layer_->GetCompositor()) 184 if (root_layer_ && !root_layer_->GetCompositor())
41 root_layer_->SetCompositor(this); 185 root_layer_->SetCompositor(this);
42 OnRootLayerChanged(); 186 root_web_layer_.removeAllChildren();
187 if (root_layer_)
188 root_web_layer_.addChild(root_layer_->web_layer());
43 } 189 }
44 190
45 void Compositor::Draw(bool force_clear) { 191 void Compositor::Draw(bool force_clear) {
46 if (!root_layer_) 192 if (!root_layer_)
47 return; 193 return;
48 194
49 NotifyStart(force_clear); 195 host_.composite();
50 DrawTree(); 196 if (!g_compositor_thread)
51 if (!CompositesAsynchronously()) {
52 NotifyEnd(); 197 NotifyEnd();
198 }
199
200 bool Compositor::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
201 if (bounds.right() > size().width() || bounds.bottom() > size().height())
202 return false;
203 // Convert to OpenGL coordinates.
204 gfx::Point new_origin(bounds.x(),
205 size().height() - bounds.height() - bounds.y());
206
207 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
208 bounds.width(), bounds.height());
209 bitmap->allocPixels();
210 SkAutoLockPixels lock_image(*bitmap);
211 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
212 if (host_.compositeAndReadback(pixels,
213 gfx::Rect(new_origin, bounds.size()))) {
214 SwizzleRGBAToBGRAAndFlip(pixels, bounds.size());
215 return true;
53 } 216 }
217 return false;
218 }
219
220 void Compositor::WidgetSizeChanged(const gfx::Size& size) {
221 if (size.IsEmpty())
222 return;
223 size_ = size;
224 host_.setViewportSize(size_);
225 root_web_layer_.setBounds(size_);
54 } 226 }
55 227
56 void Compositor::AddObserver(CompositorObserver* observer) { 228 void Compositor::AddObserver(CompositorObserver* observer) {
57 observer_list_.AddObserver(observer); 229 observer_list_.AddObserver(observer);
58 } 230 }
59 231
60 void Compositor::RemoveObserver(CompositorObserver* observer) { 232 void Compositor::RemoveObserver(CompositorObserver* observer) {
61 observer_list_.RemoveObserver(observer); 233 observer_list_.RemoveObserver(observer);
62 } 234 }
63 235
64 bool Compositor::HasObserver(CompositorObserver* observer) { 236 bool Compositor::HasObserver(CompositorObserver* observer) {
65 return observer_list_.HasObserver(observer); 237 return observer_list_.HasObserver(observer);
66 } 238 }
67 239
68 void Compositor::OnRootLayerChanged() { 240
241 void Compositor::updateAnimations(double frameBeginTime) {
242 }
243
244 void Compositor::layout() {
245 }
246
247 void Compositor::applyScrollAndScale(const WebKit::WebSize& scrollDelta,
248 float scaleFactor) {
249 }
250
251 WebKit::WebGraphicsContext3D* Compositor::createContext3D() {
252 WebKit::WebGraphicsContext3D* context;
253 if (test_compositor_enabled) {
254 // Use context that results in no rendering to the screen.
255 context = new TestWebGraphicsContext3D();
256 } else {
257 #if defined(OS_MACOSX) && !defined(USE_AURA)
258 // Non-Aura builds compile this code but doesn't call it. Unfortunately
259 // this is where we translate gfx::AcceleratedWidget to
260 // gfx::PluginWindowHandle, and they are different on non-Aura Mac.
261 // TODO(piman): remove ifdefs when AcceleratedWidget is rationalized on Mac.
262 NOTIMPLEMENTED();
263 return NULL;
264 #else
265 gfx::GLShareGroup* share_group =
266 SharedResources::GetInstance()->GetShareGroup();
267 context = new webkit::gpu::WebGraphicsContext3DInProcessImpl(
268 widget_, share_group);
269 #endif
270 }
271 WebKit::WebGraphicsContext3D::Attributes attrs;
272 context->initialize(attrs, 0, true);
273
274 CommandLine* command_line = CommandLine::ForCurrentProcess();
275 if (!command_line->HasSwitch(switches::kDisableUIVsync)) {
276 context->makeContextCurrent();
277 gfx::GLContext* gl_context = gfx::GLContext::GetCurrent();
278 gl_context->SetSwapInterval(1);
279 gl_context->ReleaseCurrent(NULL);
280 }
281
282 return context;
283 }
284
285 void Compositor::didCompleteSwapBuffers() {
286 NotifyEnd();
287 }
288
289 void Compositor::didRebindGraphicsContext(bool success) {
290 }
291
292 void Compositor::scheduleComposite() {
69 ScheduleDraw(); 293 ScheduleDraw();
70 } 294 }
71 295
72 void Compositor::DrawTree() {
73 }
74
75 bool Compositor::CompositesAsynchronously() {
76 return false;
77 }
78
79 void Compositor::SwizzleRGBAToBGRAAndFlip(unsigned char* pixels, 296 void Compositor::SwizzleRGBAToBGRAAndFlip(unsigned char* pixels,
80 const gfx::Size& image_size) { 297 const gfx::Size& image_size) {
81 // Swizzle from RGBA to BGRA 298 // Swizzle from RGBA to BGRA
82 size_t bitmap_size = 4 * image_size.width() * image_size.height(); 299 size_t bitmap_size = 4 * image_size.width() * image_size.height();
83 for(size_t i = 0; i < bitmap_size; i += 4) 300 for(size_t i = 0; i < bitmap_size; i += 4)
84 std::swap(pixels[i], pixels[i + 2]); 301 std::swap(pixels[i], pixels[i + 2]);
85 302
86 // Vertical flip to transform from GL co-ords 303 // Vertical flip to transform from GL co-ords
87 size_t row_size = 4 * image_size.width(); 304 size_t row_size = 4 * image_size.width();
88 scoped_array<unsigned char> tmp_row(new unsigned char[row_size]); 305 scoped_array<unsigned char> tmp_row(new unsigned char[row_size]);
89 for(int row = 0; row < image_size.height() / 2; row++) { 306 for(int row = 0; row < image_size.height() / 2; row++) {
90 memcpy(tmp_row.get(), 307 memcpy(tmp_row.get(),
91 &pixels[row * row_size], 308 &pixels[row * row_size],
92 row_size); 309 row_size);
93 memcpy(&pixels[row * row_size], 310 memcpy(&pixels[row * row_size],
94 &pixels[bitmap_size - (row + 1) * row_size], 311 &pixels[bitmap_size - (row + 1) * row_size],
95 row_size); 312 row_size);
96 memcpy(&pixels[bitmap_size - (row + 1) * row_size], 313 memcpy(&pixels[bitmap_size - (row + 1) * row_size],
97 tmp_row.get(), 314 tmp_row.get(),
98 row_size); 315 row_size);
99 } 316 }
100 } 317 }
101 318
102 void Compositor::NotifyEnd() { 319 void Compositor::NotifyEnd() {
103 OnNotifyEnd();
104 FOR_EACH_OBSERVER(CompositorObserver, 320 FOR_EACH_OBSERVER(CompositorObserver,
105 observer_list_, 321 observer_list_,
106 OnCompositingEnded(this)); 322 OnCompositingEnded(this));
107 } 323 }
108 324
109 void Compositor::NotifyStart(bool clear) { 325 COMPOSITOR_EXPORT void SetupTestCompositor() {
110 OnNotifyStart(clear); 326 if (!CommandLine::ForCurrentProcess()->HasSwitch(
327 switches::kDisableTestCompositor)) {
328 test_compositor_enabled = true;
329 }
330 }
331
332 COMPOSITOR_EXPORT void DisableTestCompositor() {
333 test_compositor_enabled = false;
111 } 334 }
112 335
113 } // namespace ui 336 } // 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