OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 WebLayer* LinkHighlight::clipLayer() | 99 WebLayer* LinkHighlight::clipLayer() |
100 { | 100 { |
101 return m_clipLayer.get(); | 101 return m_clipLayer.get(); |
102 } | 102 } |
103 | 103 |
104 void LinkHighlight::releaseResources() | 104 void LinkHighlight::releaseResources() |
105 { | 105 { |
106 m_node.clear(); | 106 m_node.clear(); |
107 } | 107 } |
108 | 108 |
109 RenderLayer* LinkHighlight::computeEnclosingCompositingLayer() | 109 void LinkHighlight::attachLinkHighlightToCompositingLayer(const RenderLayerModel Object* paintInvalidationContainer) |
110 { | 110 { |
111 if (!m_node || !m_node->renderer()) | 111 GraphicsLayer* newGraphicsLayer = paintInvalidationContainer->layer()->graph icsLayerBacking(); |
trchen
2014/10/29 23:57:30
I think we need to do a null check here. Multicol
chrishtr
2014/10/30 00:01:17
RenderObject::containerForPaintInvalidation should
trchen
2014/10/30 00:08:58
No I meant newGraphicsLayer may be null.
chrishtr
2014/10/30 00:21:59
Oh, yuck. Thanks for pointing that out. Fixed.
| |
112 return 0; | 112 if (!newGraphicsLayer->drawsContent()) |
113 | 113 newGraphicsLayer = paintInvalidationContainer->layer()->graphicsLayerBac kingForScrolling(); |
114 // Find the nearest enclosing composited layer and attach to it. We may need to cross frame boundaries | |
115 // to find a suitable layer. | |
116 RenderObject* renderer = m_node->renderer(); | |
117 RenderLayer* renderLayer; | |
118 do { | |
119 renderLayer = renderer->enclosingLayer()->enclosingLayerForPaintInvalida tion(); | |
120 if (!renderLayer) { | |
121 renderer = renderer->frame()->ownerRenderer(); | |
122 if (!renderer) | |
123 return 0; | |
124 } | |
125 } while (!renderLayer); | |
126 | |
127 ASSERT(renderLayer->compositingState() != NotComposited); | |
128 | |
129 GraphicsLayer* newGraphicsLayer = renderLayer->graphicsLayerBacking(); | |
130 if (!newGraphicsLayer->drawsContent()) { | |
131 newGraphicsLayer = renderLayer->graphicsLayerBackingForScrolling(); | |
132 } | |
133 | 114 |
134 m_clipLayer->setTransform(SkMatrix44(SkMatrix44::kIdentity_Constructor)); | 115 m_clipLayer->setTransform(SkMatrix44(SkMatrix44::kIdentity_Constructor)); |
135 | 116 |
136 if (m_currentGraphicsLayer != newGraphicsLayer) { | 117 if (m_currentGraphicsLayer != newGraphicsLayer) { |
137 if (m_currentGraphicsLayer) | 118 if (m_currentGraphicsLayer) |
138 clearGraphicsLayerLinkHighlightPointer(); | 119 clearGraphicsLayerLinkHighlightPointer(); |
139 | 120 |
140 m_currentGraphicsLayer = newGraphicsLayer; | 121 m_currentGraphicsLayer = newGraphicsLayer; |
141 m_currentGraphicsLayer->addLinkHighlight(this); | 122 m_currentGraphicsLayer->addLinkHighlight(this); |
142 } | 123 } |
143 | |
144 return renderLayer; | |
145 } | 124 } |
146 | 125 |
147 static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpace Quad, RenderObject* targetRenderer, RenderObject* compositedRenderer, FloatQuad& compositedSpaceQuad) | 126 static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpace Quad, RenderObject* targetRenderer, const RenderLayerModelObject* paintInvalidat ionContainer, FloatQuad& compositedSpaceQuad) |
148 { | 127 { |
149 ASSERT(targetRenderer); | 128 ASSERT(targetRenderer); |
150 ASSERT(compositedRenderer); | 129 ASSERT(paintInvalidationContainer); |
151 | |
152 for (unsigned i = 0; i < 4; ++i) { | 130 for (unsigned i = 0; i < 4; ++i) { |
153 IntPoint point; | 131 IntPoint point; |
154 switch (i) { | 132 switch (i) { |
155 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; | 133 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; |
156 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; | 134 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; |
157 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; | 135 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; |
158 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; | 136 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; |
159 } | 137 } |
160 | 138 |
139 // FIXME: this does not need to be absolute, just in the paint invalidat ion container's space. | |
161 point = targetRenderer->frame()->view()->contentsToWindow(point); | 140 point = targetRenderer->frame()->view()->contentsToWindow(point); |
162 point = compositedRenderer->frame()->view()->windowToContents(point); | 141 point = paintInvalidationContainer->frame()->view()->windowToContents(po int); |
163 FloatPoint floatPoint = compositedRenderer->absoluteToLocal(point, UseTr ansforms); | 142 FloatPoint floatPoint = paintInvalidationContainer->absoluteToLocal(poin t, UseTransforms); |
143 RenderLayer::mapPointToPaintBackingCoordinates(paintInvalidationContaine r, floatPoint); | |
164 | 144 |
165 switch (i) { | 145 switch (i) { |
166 case 0: compositedSpaceQuad.setP1(floatPoint); break; | 146 case 0: compositedSpaceQuad.setP1(floatPoint); break; |
167 case 1: compositedSpaceQuad.setP2(floatPoint); break; | 147 case 1: compositedSpaceQuad.setP2(floatPoint); break; |
168 case 2: compositedSpaceQuad.setP3(floatPoint); break; | 148 case 2: compositedSpaceQuad.setP3(floatPoint); break; |
169 case 3: compositedSpaceQuad.setP4(floatPoint); break; | 149 case 3: compositedSpaceQuad.setP4(floatPoint); break; |
170 } | 150 } |
171 } | 151 } |
172 } | 152 } |
173 | 153 |
(...skipping 16 matching lines...) Expand all Loading... | |
190 | 170 |
191 // For inline elements, absoluteQuads will return a line box based on the li ne-height | 171 // For inline elements, absoluteQuads will return a line box based on the li ne-height |
192 // and font metrics, which is technically incorrect as replaced elements lik e images | 172 // and font metrics, which is technically incorrect as replaced elements lik e images |
193 // should use their intristic height and expand the linebox as needed. To g et an | 173 // should use their intristic height and expand the linebox as needed. To g et an |
194 // appropriately sized highlight we descend into the children and have them add their | 174 // appropriately sized highlight we descend into the children and have them add their |
195 // boxes. | 175 // boxes. |
196 if (renderer->isRenderInline()) { | 176 if (renderer->isRenderInline()) { |
197 for (Node* child = NodeRenderingTraversal::firstChild(&node); child; chi ld = NodeRenderingTraversal::nextSibling(child)) | 177 for (Node* child = NodeRenderingTraversal::firstChild(&node); child; chi ld = NodeRenderingTraversal::nextSibling(child)) |
198 computeQuads(*child, outQuads); | 178 computeQuads(*child, outQuads); |
199 } else { | 179 } else { |
180 // FIXME: this does not need to be absolute, just in the paint invalidat ion container's space. | |
200 renderer->absoluteQuads(outQuads); | 181 renderer->absoluteQuads(outQuads); |
201 } | 182 } |
202 } | 183 } |
203 | 184 |
204 bool LinkHighlight::computeHighlightLayerPathAndPosition(RenderLayer* compositin gLayer) | 185 bool LinkHighlight::computeHighlightLayerPathAndPosition(const RenderLayerModelO bject* paintInvalidationContainer) |
205 { | 186 { |
206 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer) | 187 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer) |
207 return false; | 188 return false; |
208 | 189 ASSERT(paintInvalidationContainer); |
209 ASSERT(compositingLayer); | |
210 | 190 |
211 // Get quads for node in absolute coordinates. | 191 // Get quads for node in absolute coordinates. |
212 Vector<FloatQuad> quads; | 192 Vector<FloatQuad> quads; |
213 computeQuads(*m_node, quads); | 193 computeQuads(*m_node, quads); |
214 ASSERT(quads.size()); | 194 ASSERT(quads.size()); |
215 | |
216 // Adjust for offset between target graphics layer and the node's renderer. | |
217 FloatPoint positionAdjust = IntPoint(m_currentGraphicsLayer->offsetFromRende rer()); | |
218 | |
219 Path newPath; | 195 Path newPath; |
220 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { | 196 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { |
221 FloatQuad absoluteQuad = quads[quadIndex]; | 197 FloatQuad absoluteQuad = quads[quadIndex]; |
222 absoluteQuad.move(-positionAdjust.x(), -positionAdjust.y()); | |
223 | 198 |
224 // Transform node quads in target absolute coords to local coordinates i n the compositor layer. | 199 // Transform node quads in target absolute coords to local coordinates i n the compositor layer. |
225 FloatQuad transformedQuad; | 200 FloatQuad transformedQuad; |
226 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer() , compositingLayer->renderer(), transformedQuad); | 201 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer() , paintInvalidationContainer, transformedQuad); |
227 | 202 |
228 // FIXME: for now, we'll only use rounded paths if we have a single node quad. The reason for this is that | 203 // FIXME: for now, we'll only use rounded paths if we have a single node quad. The reason for this is that |
229 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) which end up looking like sausage | 204 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) which end up looking like sausage |
230 // links: these should ideally be merged into a single rect before creat ing the path, but that's | 205 // links: these should ideally be merged into a single rect before creat ing the path, but that's |
231 // another CL. | 206 // another CL. |
232 if (quads.size() == 1 && transformedQuad.isRectilinear() | 207 if (quads.size() == 1 && transformedQuad.isRectilinear() |
233 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna bled()) { | 208 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna bled()) { |
234 FloatSize rectRoundingRadii(3, 3); | 209 FloatSize rectRoundingRadii(3, 3); |
235 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa dii); | 210 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa dii); |
236 } else | 211 } else |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 releaseResources(); | 299 releaseResources(); |
325 } | 300 } |
326 | 301 |
327 void LinkHighlight::updateGeometry() | 302 void LinkHighlight::updateGeometry() |
328 { | 303 { |
329 // To avoid unnecessary updates (e.g. other entities have requested animatio ns from our WebViewImpl), | 304 // To avoid unnecessary updates (e.g. other entities have requested animatio ns from our WebViewImpl), |
330 // only proceed if we actually requested an update. | 305 // only proceed if we actually requested an update. |
331 if (!m_geometryNeedsUpdate) | 306 if (!m_geometryNeedsUpdate) |
332 return; | 307 return; |
333 | 308 |
309 if (!m_node || !m_node->renderer()) | |
310 return; | |
311 | |
334 m_geometryNeedsUpdate = false; | 312 m_geometryNeedsUpdate = false; |
335 | 313 const RenderLayerModelObject* paintInvalidationContainer = m_node->renderer( )->containerForPaintInvalidation(); |
336 RenderLayer* compositingLayer = computeEnclosingCompositingLayer(); | 314 attachLinkHighlightToCompositingLayer(paintInvalidationContainer); |
337 if (compositingLayer && computeHighlightLayerPathAndPosition(compositingLaye r)) { | 315 if (paintInvalidationContainer && computeHighlightLayerPathAndPosition(paint InvalidationContainer)) { |
338 // We only need to invalidate the layer if the highlight size has change d, otherwise | 316 // We only need to invalidate the layer if the highlight size has change d, otherwise |
339 // we can just re-position the layer without needing to repaint. | 317 // we can just re-position the layer without needing to repaint. |
340 m_contentLayer->layer()->invalidate(); | 318 m_contentLayer->layer()->invalidate(); |
341 | 319 |
342 if (m_currentGraphicsLayer) | 320 if (m_currentGraphicsLayer) |
343 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position() .x, layer()->position().y, layer()->bounds().width, layer()->bounds().height)); | 321 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position() .x, layer()->position().y, layer()->bounds().width, layer()->bounds().height)); |
344 } else if (!m_node || !m_node->renderer()) { | 322 } else if (!m_node || !m_node->renderer()) { |
345 clearGraphicsLayerLinkHighlightPointer(); | 323 clearGraphicsLayerLinkHighlightPointer(); |
346 releaseResources(); | 324 releaseResources(); |
347 } | 325 } |
(...skipping 10 matching lines...) Expand all Loading... | |
358 // Make sure we update geometry on the next callback from WebViewImpl::layou t(). | 336 // Make sure we update geometry on the next callback from WebViewImpl::layou t(). |
359 m_geometryNeedsUpdate = true; | 337 m_geometryNeedsUpdate = true; |
360 } | 338 } |
361 | 339 |
362 WebLayer* LinkHighlight::layer() | 340 WebLayer* LinkHighlight::layer() |
363 { | 341 { |
364 return clipLayer(); | 342 return clipLayer(); |
365 } | 343 } |
366 | 344 |
367 } // namespace blink | 345 } // namespace blink |
OLD | NEW |