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

Side by Side Diff: services/gfx/compositor/backend/gpu_rasterizer.cc

Issue 1552963002: Initial checkin of the new Mozart compositor. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-11
Patch Set: Created 4 years, 11 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
OLDNEW
(Empty)
1 // Copyright 2015 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 "services/gfx/compositor/backend/gpu_rasterizer.h"
6
7 #ifndef GL_GLEXT_PROTOTYPES
8 #define GL_GLEXT_PROTOTYPES
9 #endif
10
11 #include <GLES2/gl2.h>
12 #include <GLES2/gl2extmojo.h>
13 #include <MGL/mgl.h>
14 #include <MGL/mgl_onscreen.h>
15
16 #include "base/bind.h"
17 #include "base/location.h"
18 #include "base/logging.h"
19 #include "services/gfx/compositor/backend/vsync_scheduler.h"
20 #include "services/gfx/compositor/render/render_frame.h"
21
22 namespace compositor {
23
24 GpuRasterizer::GpuRasterizer(mojo::ContextProviderPtr context_provider,
25 const std::shared_ptr<VsyncScheduler>& scheduler,
26 const scoped_refptr<base::TaskRunner>& task_runner,
27 const base::Closure& error_callback)
28 : context_provider_(context_provider.Pass()),
29 scheduler_(scheduler),
30 task_runner_(task_runner),
31 error_callback_(error_callback),
32 viewport_parameter_listener_binding_(this) {
33 DCHECK(context_provider_);
34 context_provider_.set_connection_error_handler(
35 base::Bind(&GpuRasterizer::OnContextProviderConnectionError,
36 base::Unretained(this)));
37 CreateContext();
38 }
39
40 GpuRasterizer::~GpuRasterizer() {
41 DestroyContext();
42 }
43
44 void GpuRasterizer::CreateContext() {
45 mojo::ViewportParameterListenerPtr viewport_parameter_listener;
46 viewport_parameter_listener_binding_.Bind(
47 GetProxy(&viewport_parameter_listener));
48 context_provider_->Create(
49 viewport_parameter_listener.Pass(),
50 base::Bind(&GpuRasterizer::InitContext, base::Unretained(this)));
51 }
52
53 void GpuRasterizer::InitContext(mojo::CommandBufferPtr command_buffer) {
54 DCHECK(!gl_context_);
55 DCHECK(!ganesh_context_);
56 DCHECK(!ganesh_surface_);
57
58 if (!command_buffer) {
59 LOG(ERROR) << "Could not create GL context.";
60 PostErrorCallback();
61 return;
62 }
63
64 gl_context_ = mojo::GLContext::CreateFromCommandBuffer(command_buffer.Pass());
65 gl_context_->AddObserver(this);
66 ganesh_context_.reset(new mojo::skia::GaneshContext(gl_context_));
67
68 if (current_frame_)
69 Draw();
70 }
71
72 void GpuRasterizer::DestroyContext() {
73 if (gl_context_) {
74 scheduler_->Stop();
75
76 // Release objects that belong to special scopes.
77 {
78 mojo::skia::GaneshContext::Scope ganesh_scope(ganesh_context_.get());
79 PaintingScope painting_scope(ganesh_scope, &painting_cache_);
80 ganesh_surface_.reset();
81 painting_cache_.Clear(painting_scope);
82 }
83
84 // Release the ganesh context first.
85 ganesh_context_.reset();
86
87 // Now release the GL context.
88 gl_context_->Destroy();
89 gl_context_.reset();
90 }
91 }
92
93 void GpuRasterizer::OnContextProviderConnectionError() {
94 LOG(ERROR) << "Context provider connection lost.";
95 PostErrorCallback();
96 }
97
98 void GpuRasterizer::OnContextLost() {
99 LOG(WARNING) << "GL context lost, recreating it.";
100 DestroyContext();
101 CreateContext();
102 }
103
104 void GpuRasterizer::OnVSyncParametersUpdated(int64_t timebase,
105 int64_t interval) {
106 DVLOG(1) << "Vsync parameters: timebase=" << timebase
107 << ", interval=" << interval;
108
109 if (!gl_context_)
110 return;
111
112 // TODO(jeffbrown): This shouldn't be hardcoded.
113 // Need to do some real tuning and possibly determine values adaptively.
114 int64_t update_phase = -interval;
115 int64_t snapshot_phase = -interval / 8;
116 int64_t presentation_phase = interval;
117 if (!scheduler_->Start(timebase, interval, update_phase, snapshot_phase,
118 presentation_phase)) {
119 LOG(ERROR) << "Received invalid vsync parameters: timebase=" << timebase
120 << ", interval=" << interval;
121 PostErrorCallback();
122 }
123 }
124
125 void GpuRasterizer::SubmitFrame(const std::shared_ptr<RenderFrame>& frame) {
126 DCHECK(frame);
127
128 if (current_frame_ == frame)
129 return;
130
131 current_frame_ = frame;
132 if (gl_context_)
133 Draw();
134 }
135
136 void GpuRasterizer::Draw() {
137 DCHECK(gl_context_);
138 DCHECK(ganesh_context_);
139 DCHECK(current_frame_);
140
141 gl_context_->MakeCurrent();
142
143 // Update the viewport.
144 const SkRect& viewport = current_frame_->viewport();
145 bool stale_surface = false;
146 if (!ganesh_surface_ ||
147 ganesh_surface_->surface()->width() != viewport.width() ||
148 ganesh_surface_->surface()->height() != viewport.height()) {
149 glViewport(viewport.x(), viewport.y(), viewport.width(), viewport.height());
150 glResizeCHROMIUM(viewport.width(), viewport.height(), 1.0f);
151 stale_surface = true;
152 }
153
154 // Paint the frame.
155 {
156 mojo::skia::GaneshContext::Scope ganesh_scope(ganesh_context_.get());
157 PaintingScope painting_scope(ganesh_scope, &painting_cache_);
158
159 if (stale_surface)
160 ganesh_surface_.reset(
161 new mojo::skia::GaneshFramebufferSurface(ganesh_scope));
162
163 current_frame_->Paint(painting_scope, ganesh_surface_->canvas());
164 }
165
166 // Swap buffers.
167 MGLSwapBuffers();
168 }
abarth 2016/01/10 04:22:09 Usually you want some sort of signal to come out o
jeffbrown 2016/01/16 03:28:31 It doesn't. :) I'll fix this later, as we discus
169
170 void GpuRasterizer::PostErrorCallback() {
171 task_runner_->PostTask(FROM_HERE, error_callback_);
172 }
173
174 } // namespace compositor
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698