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

Side by Side Diff: cc/direct_renderer.cc

Issue 12912006: Part 4 of cc/ directory shuffles: output (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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
OLDNEW
(Empty)
1 // Copyright 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 "cc/direct_renderer.h"
6
7 #include <vector>
8
9 #include "base/debug/trace_event.h"
10 #include "base/metrics/histogram.h"
11 #include "cc/base/math_util.h"
12 #include "cc/draw_quad.h"
13 #include "ui/gfx/rect_conversions.h"
14 #include "ui/gfx/transform.h"
15
16 static gfx::Transform OrthoProjectionMatrix(float left,
17 float right,
18 float bottom,
19 float top) {
20 // Use the standard formula to map the clipping frustum to the cube from
21 // [-1, -1, -1] to [1, 1, 1].
22 float delta_x = right - left;
23 float delta_y = top - bottom;
24 gfx::Transform proj;
25 if (!delta_x || !delta_y)
26 return proj;
27 proj.matrix().setDouble(0, 0, 2.0f / delta_x);
28 proj.matrix().setDouble(0, 3, -(right + left) / delta_x);
29 proj.matrix().setDouble(1, 1, 2.0f / delta_y);
30 proj.matrix().setDouble(1, 3, -(top + bottom) / delta_y);
31
32 // Z component of vertices is always set to zero as we don't use the depth
33 // buffer while drawing.
34 proj.matrix().setDouble(2, 2, 0);
35
36 return proj;
37 }
38
39 static gfx::Transform window_matrix(int x, int y, int width, int height) {
40 gfx::Transform canvas;
41
42 // Map to window position and scale up to pixel coordinates.
43 canvas.Translate3d(x, y, 0);
44 canvas.Scale3d(width, height, 0);
45
46 // Map from ([-1, -1] to [1, 1]) -> ([0, 0] to [1, 1])
47 canvas.Translate3d(0.5, 0.5, 0.5);
48 canvas.Scale3d(0.5, 0.5, 0.5);
49
50 return canvas;
51 }
52
53 namespace cc {
54
55 DirectRenderer::DrawingFrame::DrawingFrame()
56 : root_render_pass(NULL),
57 current_render_pass(NULL),
58 current_texture(NULL),
59 flipped_y(false) {}
60
61 DirectRenderer::DrawingFrame::~DrawingFrame() {}
62
63 //
64 // static
65 gfx::RectF DirectRenderer::QuadVertexRect() {
66 return gfx::RectF(-0.5f, -0.5f, 1.f, 1.f);
67 }
68
69 // static
70 void DirectRenderer::QuadRectTransform(gfx::Transform* quad_rect_transform,
71 const gfx::Transform& quadTransform,
72 const gfx::RectF& quadRect) {
73 *quad_rect_transform = quadTransform;
74 quad_rect_transform->Translate(0.5 * quadRect.width() + quadRect.x(),
75 0.5 * quadRect.height() + quadRect.y());
76 quad_rect_transform->Scale(quadRect.width(), quadRect.height());
77 }
78
79 // static
80 void DirectRenderer::InitializeMatrices(DrawingFrame& frame,
81 gfx::Rect draw_rect,
82 bool flip_y) {
83 if (flip_y) {
84 frame.projection_matrix = OrthoProjectionMatrix(draw_rect.x(),
85 draw_rect.right(),
86 draw_rect.bottom(),
87 draw_rect.y());
88 } else {
89 frame.projection_matrix = OrthoProjectionMatrix(draw_rect.x(),
90 draw_rect.right(),
91 draw_rect.y(),
92 draw_rect.bottom());
93 }
94 frame.window_matrix =
95 window_matrix(0, 0, draw_rect.width(), draw_rect.height());
96 frame.flipped_y = flip_y;
97 }
98
99 // static
100 gfx::Rect DirectRenderer::MoveScissorToWindowSpace(
101 const DrawingFrame& frame, const gfx::RectF& scissor_rect) {
102 gfx::Rect scissor_rect_in_canvas_space = gfx::ToEnclosingRect(scissor_rect);
103 // The scissor coordinates must be supplied in viewport space so we need to
104 // offset by the relative position of the top left corner of the current
105 // render pass.
106 gfx::Rect framebuffer_output_rect = frame.current_render_pass->output_rect;
107 scissor_rect_in_canvas_space.set_x(
108 scissor_rect_in_canvas_space.x() - framebuffer_output_rect.x());
109 if (frame.flipped_y && !frame.current_texture) {
110 scissor_rect_in_canvas_space.set_y(
111 framebuffer_output_rect.height() -
112 (scissor_rect_in_canvas_space.bottom() - framebuffer_output_rect.y()));
113 } else {
114 scissor_rect_in_canvas_space.set_y(
115 scissor_rect_in_canvas_space.y() - framebuffer_output_rect.y());
116 }
117 return scissor_rect_in_canvas_space;
118 }
119
120 DirectRenderer::DirectRenderer(RendererClient* client,
121 ResourceProvider* resource_provider)
122 : Renderer(client),
123 resource_provider_(resource_provider) {}
124
125 DirectRenderer::~DirectRenderer() {}
126
127 void DirectRenderer::SetEnlargePassTextureAmountForTesting(
128 gfx::Vector2d amount) {
129 enlarge_pass_texture_amount_ = amount;
130 }
131
132 void DirectRenderer::DecideRenderPassAllocationsForFrame(
133 const RenderPassList& render_passes_in_draw_order) {
134 base::hash_map<RenderPass::Id, const RenderPass*> renderPassesInFrame;
135 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i)
136 renderPassesInFrame.insert(std::pair<RenderPass::Id, const RenderPass*>(
137 render_passes_in_draw_order[i]->id, render_passes_in_draw_order[i]));
138
139 std::vector<RenderPass::Id> passes_to_delete;
140 ScopedPtrHashMap<RenderPass::Id, CachedResource>::const_iterator passIterator;
141 for (passIterator = render_pass_textures_.begin();
142 passIterator != render_pass_textures_.end();
143 ++passIterator) {
144 base::hash_map<RenderPass::Id, const RenderPass*>::const_iterator it =
145 renderPassesInFrame.find(passIterator->first);
146 if (it == renderPassesInFrame.end()) {
147 passes_to_delete.push_back(passIterator->first);
148 continue;
149 }
150
151 const RenderPass* render_pass_in_frame = it->second;
152 gfx::Size required_size = RenderPassTextureSize(render_pass_in_frame);
153 GLenum required_format = RenderPassTextureFormat(render_pass_in_frame);
154 CachedResource* texture = passIterator->second;
155 DCHECK(texture);
156
157 bool size_appropriate = texture->size().width() >= required_size.width() &&
158 texture->size().height() >= required_size.height();
159 if (texture->id() &&
160 (!size_appropriate || texture->format() != required_format))
161 texture->Free();
162 }
163
164 // Delete RenderPass textures from the previous frame that will not be used
165 // again.
166 for (size_t i = 0; i < passes_to_delete.size(); ++i)
167 render_pass_textures_.erase(passes_to_delete[i]);
168
169 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) {
170 if (!render_pass_textures_.contains(render_passes_in_draw_order[i]->id)) {
171 scoped_ptr<CachedResource> texture =
172 CachedResource::Create(resource_provider_);
173 render_pass_textures_.set(render_passes_in_draw_order[i]->id,
174 texture.Pass());
175 }
176 }
177 }
178
179 void DirectRenderer::DrawFrame(RenderPassList& render_passes_in_draw_order) {
180 TRACE_EVENT0("cc", "DirectRenderer::drawFrame");
181 UMA_HISTOGRAM_COUNTS("Renderer4.renderPassCount",
182 render_passes_in_draw_order.size());
183
184 const RenderPass* root_render_pass = render_passes_in_draw_order.back();
185 DCHECK(root_render_pass);
186
187 DrawingFrame frame;
188 frame.root_render_pass = root_render_pass;
189 frame.root_damage_rect =
190 Capabilities().using_partial_swap ?
191 root_render_pass->damage_rect : root_render_pass->output_rect;
192 frame.root_damage_rect.Intersect(gfx::Rect(gfx::Point(), ViewportSize()));
193
194 BeginDrawingFrame(frame);
195 for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i)
196 DrawRenderPass(frame, render_passes_in_draw_order[i]);
197 FinishDrawingFrame(frame);
198
199 render_passes_in_draw_order.clear();
200 }
201
202 gfx::RectF DirectRenderer::ComputeScissorRectForRenderPass(
203 const DrawingFrame& frame) {
204 gfx::RectF render_pass_scissor = frame.current_render_pass->output_rect;
205
206 if (frame.root_damage_rect == frame.root_render_pass->output_rect)
207 return render_pass_scissor;
208
209 gfx::Transform inverseTransform(gfx::Transform::kSkipInitialization);
210 if (frame.current_render_pass->transform_to_root_target.GetInverse(
211 &inverseTransform)) {
212 // Only intersect inverse-projected damage if the transform is invertible.
213 gfx::RectF damage_rect_in_render_pass_space =
214 MathUtil::ProjectClippedRect(inverseTransform, frame.root_damage_rect);
215 render_pass_scissor.Intersect(damage_rect_in_render_pass_space);
216 }
217
218 return render_pass_scissor;
219 }
220
221 void DirectRenderer::SetScissorStateForQuad(const DrawingFrame& frame,
222 const DrawQuad& quad) {
223 if (quad.isClipped()) {
224 gfx::RectF quad_scissor_rect = quad.clipRect();
225 SetScissorTestRect(MoveScissorToWindowSpace(frame, quad_scissor_rect));
226 } else {
227 EnsureScissorTestDisabled();
228 }
229 }
230
231 void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor(
232 const DrawingFrame& frame,
233 const DrawQuad& quad,
234 const gfx::RectF& render_pass_scissor,
235 bool* should_skip_quad) {
236 gfx::RectF quad_scissor_rect = render_pass_scissor;
237
238 if (quad.isClipped())
239 quad_scissor_rect.Intersect(quad.clipRect());
240
241 if (quad_scissor_rect.IsEmpty()) {
242 *should_skip_quad = true;
243 return;
244 }
245
246 *should_skip_quad = false;
247 SetScissorTestRect(MoveScissorToWindowSpace(frame, quad_scissor_rect));
248 }
249
250 void DirectRenderer::FinishDrawingQuadList() {}
251
252 void DirectRenderer::DrawRenderPass(DrawingFrame& frame,
253 const RenderPass* render_pass) {
254 TRACE_EVENT0("cc", "DirectRenderer::drawRenderPass");
255 if (!UseRenderPass(frame, render_pass))
256 return;
257
258 bool using_scissor_as_optimization = Capabilities().using_partial_swap;
259 gfx::RectF render_pass_scissor;
260
261 if (using_scissor_as_optimization) {
262 render_pass_scissor = ComputeScissorRectForRenderPass(frame);
263 SetScissorTestRect(MoveScissorToWindowSpace(frame, render_pass_scissor));
264 }
265
266 if (frame.current_render_pass != frame.root_render_pass ||
267 client_->ShouldClearRootRenderPass()) {
268 if (!using_scissor_as_optimization)
269 EnsureScissorTestDisabled();
270 ClearFramebuffer(frame);
271 }
272
273 const QuadList& quad_list = render_pass->quad_list;
274 for (QuadList::constBackToFrontIterator it = quad_list.backToFrontBegin();
275 it != quad_list.backToFrontEnd();
276 ++it) {
277 const DrawQuad& quad = *(*it);
278 bool should_skip_quad = false;
279
280 if (using_scissor_as_optimization) {
281 SetScissorStateForQuadWithRenderPassScissor(
282 frame, quad, render_pass_scissor, &should_skip_quad);
283 } else {
284 SetScissorStateForQuad(frame, quad);
285 }
286
287 if (!should_skip_quad)
288 DoDrawQuad(frame, *it);
289 }
290 FinishDrawingQuadList();
291
292 CachedResource* texture = render_pass_textures_.get(render_pass->id);
293 if (texture) {
294 texture->set_is_complete(
295 !render_pass->has_occlusion_from_outside_target_surface);
296 }
297 }
298
299 bool DirectRenderer::UseRenderPass(DrawingFrame& frame,
300 const RenderPass* render_pass) {
301 frame.current_render_pass = render_pass;
302 frame.current_texture = NULL;
303
304 if (render_pass == frame.root_render_pass) {
305 BindFramebufferToOutputSurface(frame);
306 InitializeMatrices(frame, render_pass->output_rect, FlippedFramebuffer());
307 SetDrawViewportSize(render_pass->output_rect.size());
308 return true;
309 }
310
311 CachedResource* texture = render_pass_textures_.get(render_pass->id);
312 DCHECK(texture);
313
314 gfx::Size size = RenderPassTextureSize(render_pass);
315 size.Enlarge(enlarge_pass_texture_amount_.x(),
316 enlarge_pass_texture_amount_.y());
317 if (!texture->id() &&
318 !texture->Allocate(size,
319 RenderPassTextureFormat(render_pass),
320 ResourceProvider::TextureUsageFramebuffer))
321 return false;
322
323 return BindFramebufferToTexture(frame, texture, render_pass->output_rect);
324 }
325
326 bool DirectRenderer::HaveCachedResourcesForRenderPassId(RenderPass::Id id)
327 const {
328 if (!Settings().cacheRenderPassContents)
329 return false;
330
331 CachedResource* texture = render_pass_textures_.get(id);
332 return texture && texture->id() && texture->is_complete();
333 }
334
335 // static
336 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) {
337 return render_pass->output_rect.size();
338 }
339
340 // static
341 GLenum DirectRenderer::RenderPassTextureFormat(const RenderPass* render_pass) {
342 return GL_RGBA;
343 }
344
345 } // namespace cc
OLDNEW
« no previous file with comments | « cc/direct_renderer.h ('k') | cc/geometry_binding.h » ('j') | content/common/view_messages.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698