OLD | NEW |
| (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 "config.h" | |
6 | |
7 #include "CCDirectRenderer.h" | |
8 | |
9 #include "CCMathUtil.h" | |
10 #include <public/WebTransformationMatrix.h> | |
11 #include <vector> | |
12 | |
13 using WebKit::WebTransformationMatrix; | |
14 | |
15 static WebTransformationMatrix orthoProjectionMatrix(float left, float right, fl
oat bottom, float top) | |
16 { | |
17 // Use the standard formula to map the clipping frustum to the cube from | |
18 // [-1, -1, -1] to [1, 1, 1]. | |
19 float deltaX = right - left; | |
20 float deltaY = top - bottom; | |
21 WebTransformationMatrix proj; | |
22 if (!deltaX || !deltaY) | |
23 return proj; | |
24 proj.setM11(2.0f / deltaX); | |
25 proj.setM41(-(right + left) / deltaX); | |
26 proj.setM22(2.0f / deltaY); | |
27 proj.setM42(-(top + bottom) / deltaY); | |
28 | |
29 // Z component of vertices is always set to zero as we don't use the depth b
uffer | |
30 // while drawing. | |
31 proj.setM33(0); | |
32 | |
33 return proj; | |
34 } | |
35 | |
36 static WebTransformationMatrix windowMatrix(int x, int y, int width, int height) | |
37 { | |
38 WebTransformationMatrix canvas; | |
39 | |
40 // Map to window position and scale up to pixel coordinates. | |
41 canvas.translate3d(x, y, 0); | |
42 canvas.scale3d(width, height, 0); | |
43 | |
44 // Map from ([-1, -1] to [1, 1]) -> ([0, 0] to [1, 1]) | |
45 canvas.translate3d(0.5, 0.5, 0.5); | |
46 canvas.scale3d(0.5, 0.5, 0.5); | |
47 | |
48 return canvas; | |
49 } | |
50 | |
51 namespace cc { | |
52 | |
53 CCDirectRenderer::DrawingFrame::DrawingFrame() | |
54 : rootRenderPass(0) | |
55 , currentRenderPass(0) | |
56 , currentTexture(0) | |
57 , flippedY(false) | |
58 { | |
59 } | |
60 | |
61 CCDirectRenderer::DrawingFrame::~DrawingFrame() | |
62 { | |
63 } | |
64 | |
65 // | |
66 // static | |
67 FloatRect CCDirectRenderer::quadVertexRect() | |
68 { | |
69 return FloatRect(-0.5, -0.5, 1, 1); | |
70 } | |
71 | |
72 // static | |
73 void CCDirectRenderer::quadRectTransform(WebKit::WebTransformationMatrix* quadRe
ctTransform, const WebKit::WebTransformationMatrix& quadTransform, const FloatRe
ct& quadRect) | |
74 { | |
75 *quadRectTransform = quadTransform; | |
76 quadRectTransform->translate(0.5 * quadRect.width() + quadRect.x(), 0.5 * qu
adRect.height() + quadRect.y()); | |
77 quadRectTransform->scaleNonUniform(quadRect.width(), quadRect.height()); | |
78 } | |
79 | |
80 // static | |
81 void CCDirectRenderer::initializeMatrices(DrawingFrame& frame, const IntRect& dr
awRect, bool flipY) | |
82 { | |
83 if (flipY) | |
84 frame.projectionMatrix = orthoProjectionMatrix(drawRect.x(), drawRect.ma
xX(), drawRect.maxY(), drawRect.y()); | |
85 else | |
86 frame.projectionMatrix = orthoProjectionMatrix(drawRect.x(), drawRect.ma
xX(), drawRect.y(), drawRect.maxY()); | |
87 frame.windowMatrix = windowMatrix(0, 0, drawRect.width(), drawRect.height())
; | |
88 frame.flippedY = flipY; | |
89 } | |
90 | |
91 // static | |
92 IntRect CCDirectRenderer::moveScissorToWindowSpace(const DrawingFrame& frame, Fl
oatRect scissorRect) | |
93 { | |
94 IntRect scissorRectInCanvasSpace = enclosingIntRect(scissorRect); | |
95 // The scissor coordinates must be supplied in viewport space so we need to
offset | |
96 // by the relative position of the top left corner of the current render pas
s. | |
97 IntRect framebufferOutputRect = frame.currentRenderPass->outputRect(); | |
98 scissorRectInCanvasSpace.setX(scissorRectInCanvasSpace.x() - framebufferOutp
utRect.x()); | |
99 if (frame.flippedY && !frame.currentTexture) | |
100 scissorRectInCanvasSpace.setY(framebufferOutputRect.height() - (scissorR
ectInCanvasSpace.maxY() - framebufferOutputRect.y())); | |
101 else | |
102 scissorRectInCanvasSpace.setY(scissorRectInCanvasSpace.y() - framebuffer
OutputRect.y()); | |
103 return scissorRectInCanvasSpace; | |
104 } | |
105 | |
106 CCDirectRenderer::CCDirectRenderer(CCRendererClient* client, CCResourceProvider*
resourceProvider) | |
107 : CCRenderer(client) | |
108 , m_resourceProvider(resourceProvider) | |
109 { | |
110 } | |
111 | |
112 CCDirectRenderer::~CCDirectRenderer() | |
113 { | |
114 } | |
115 | |
116 void CCDirectRenderer::decideRenderPassAllocationsForFrame(const CCRenderPassLis
t& renderPassesInDrawOrder) | |
117 { | |
118 base::hash_map<CCRenderPass::Id, const CCRenderPass*> renderPassesInFrame; | |
119 for (size_t i = 0; i < renderPassesInDrawOrder.size(); ++i) | |
120 renderPassesInFrame.insert(std::pair<CCRenderPass::Id, const CCRenderPas
s*>(renderPassesInDrawOrder[i]->id(), renderPassesInDrawOrder[i])); | |
121 | |
122 std::vector<CCRenderPass::Id> passesToDelete; | |
123 ScopedPtrHashMap<CCRenderPass::Id, CachedTexture>::const_iterator passIterat
or; | |
124 for (passIterator = m_renderPassTextures.begin(); passIterator != m_renderPa
ssTextures.end(); ++passIterator) { | |
125 base::hash_map<CCRenderPass::Id, const CCRenderPass*>::const_iterator it
= renderPassesInFrame.find(passIterator->first); | |
126 if (it == renderPassesInFrame.end()) { | |
127 passesToDelete.push_back(passIterator->first); | |
128 continue; | |
129 } | |
130 | |
131 const CCRenderPass* renderPassInFrame = it->second; | |
132 const IntSize& requiredSize = renderPassTextureSize(renderPassInFrame); | |
133 GC3Denum requiredFormat = renderPassTextureFormat(renderPassInFrame); | |
134 CachedTexture* texture = passIterator->second; | |
135 ASSERT(texture); | |
136 | |
137 if (texture->id() && (texture->size() != requiredSize || texture->format
() != requiredFormat)) | |
138 texture->free(); | |
139 } | |
140 | |
141 // Delete RenderPass textures from the previous frame that will not be used
again. | |
142 for (size_t i = 0; i < passesToDelete.size(); ++i) | |
143 m_renderPassTextures.erase(passesToDelete[i]); | |
144 | |
145 for (size_t i = 0; i < renderPassesInDrawOrder.size(); ++i) { | |
146 if (!m_renderPassTextures.contains(renderPassesInDrawOrder[i]->id())) { | |
147 scoped_ptr<CachedTexture> texture = CachedTexture::create(m_resourcePr
ovider); | |
148 m_renderPassTextures.set(renderPassesInDrawOrder[i]->id(), texture.P
ass()); | |
149 } | |
150 } | |
151 } | |
152 | |
153 void CCDirectRenderer::drawFrame(const CCRenderPassList& renderPassesInDrawOrder
, const CCRenderPassIdHashMap& renderPassesById) | |
154 { | |
155 const CCRenderPass* rootRenderPass = renderPassesInDrawOrder.back(); | |
156 ASSERT(rootRenderPass); | |
157 | |
158 DrawingFrame frame; | |
159 frame.renderPassesById = &renderPassesById; | |
160 frame.rootRenderPass = rootRenderPass; | |
161 frame.rootDamageRect = capabilities().usingPartialSwap ? rootRenderPass->dam
ageRect() : rootRenderPass->outputRect(); | |
162 frame.rootDamageRect.intersect(IntRect(IntPoint::zero(), viewportSize())); | |
163 | |
164 beginDrawingFrame(frame); | |
165 for (size_t i = 0; i < renderPassesInDrawOrder.size(); ++i) | |
166 drawRenderPass(frame, renderPassesInDrawOrder[i]); | |
167 finishDrawingFrame(frame); | |
168 } | |
169 | |
170 void CCDirectRenderer::drawRenderPass(DrawingFrame& frame, const CCRenderPass* r
enderPass) | |
171 { | |
172 if (!useRenderPass(frame, renderPass)) | |
173 return; | |
174 | |
175 frame.scissorRectInRenderPassSpace = frame.currentRenderPass->outputRect(); | |
176 if (frame.rootDamageRect != frame.rootRenderPass->outputRect()) { | |
177 WebTransformationMatrix inverseTransformToRoot = frame.currentRenderPass
->transformToRootTarget().inverse(); | |
178 frame.scissorRectInRenderPassSpace.intersect(CCMathUtil::projectClippedR
ect(inverseTransformToRoot, frame.rootDamageRect)); | |
179 } | |
180 | |
181 enableScissorTestRect(moveScissorToWindowSpace(frame, frame.scissorRectInRen
derPassSpace)); | |
182 clearFramebuffer(frame); | |
183 | |
184 const CCQuadList& quadList = renderPass->quadList(); | |
185 for (CCQuadList::constBackToFrontIterator it = quadList.backToFrontBegin();
it != quadList.backToFrontEnd(); ++it) { | |
186 FloatRect quadScissorRect = frame.scissorRectInRenderPassSpace; | |
187 quadScissorRect.intersect((*it)->clippedRectInTarget()); | |
188 if (!quadScissorRect.isEmpty()) { | |
189 enableScissorTestRect(moveScissorToWindowSpace(frame, quadScissorRec
t)); | |
190 drawQuad(frame, *it); | |
191 } | |
192 } | |
193 | |
194 CachedTexture* texture = m_renderPassTextures.get(renderPass->id()); | |
195 if (texture) | |
196 texture->setIsComplete(!renderPass->hasOcclusionFromOutsideTargetSurface
()); | |
197 } | |
198 | |
199 bool CCDirectRenderer::useRenderPass(DrawingFrame& frame, const CCRenderPass* re
nderPass) | |
200 { | |
201 frame.currentRenderPass = renderPass; | |
202 frame.currentTexture = 0; | |
203 | |
204 if (renderPass == frame.rootRenderPass) { | |
205 bindFramebufferToOutputSurface(frame); | |
206 initializeMatrices(frame, renderPass->outputRect(), flippedFramebuffer()
); | |
207 setDrawViewportSize(renderPass->outputRect().size()); | |
208 return true; | |
209 } | |
210 | |
211 CachedTexture* texture = m_renderPassTextures.get(renderPass->id()); | |
212 ASSERT(texture); | |
213 if (!texture->id() && !texture->allocate(CCRenderer::ImplPool, renderPassTex
tureSize(renderPass), renderPassTextureFormat(renderPass), CCResourceProvider::T
extureUsageFramebuffer)) | |
214 return false; | |
215 | |
216 return bindFramebufferToTexture(frame, texture, renderPass->outputRect()); | |
217 } | |
218 | |
219 bool CCDirectRenderer::haveCachedResourcesForRenderPassId(CCRenderPass::Id id) c
onst | |
220 { | |
221 CachedTexture* texture = m_renderPassTextures.get(id); | |
222 return texture && texture->id() && texture->isComplete(); | |
223 } | |
224 | |
225 // static | |
226 IntSize CCDirectRenderer::renderPassTextureSize(const CCRenderPass* pass) | |
227 { | |
228 return pass->outputRect().size(); | |
229 } | |
230 | |
231 // static | |
232 GC3Denum CCDirectRenderer::renderPassTextureFormat(const CCRenderPass*) | |
233 { | |
234 return GraphicsContext3D::RGBA; | |
235 } | |
236 | |
237 } | |
OLD | NEW |