Disable StorageInfoProviderTest.* on Valgrind bots.
[chromium-blink-merge.git] / cc / scrollbar_layer.cc
blob9c7ae732c0accee5f01775c524c77d7f72ec8fab
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.
5 #include "cc/scrollbar_layer.h"
7 #include "base/basictypes.h"
8 #include "base/debug/trace_event.h"
9 #include "cc/layer_painter.h"
10 #include "cc/layer_tree_host.h"
11 #include "cc/resource_update_queue.h"
12 #include "cc/scrollbar_layer_impl.h"
13 #include "ui/gfx/rect_conversions.h"
14 #include <public/WebRect.h>
16 using WebKit::WebRect;
18 namespace cc {
20 scoped_ptr<LayerImpl> ScrollbarLayer::createLayerImpl()
22 return ScrollbarLayerImpl::create(id()).PassAs<LayerImpl>();
25 scoped_refptr<ScrollbarLayer> ScrollbarLayer::create(scoped_ptr<WebKit::WebScrollbar> scrollbar, WebKit::WebScrollbarThemePainter painter, scoped_ptr<WebKit::WebScrollbarThemeGeometry> geometry, int scrollLayerId)
27 return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(), painter, geometry.Pass(), scrollLayerId));
30 ScrollbarLayer::ScrollbarLayer(scoped_ptr<WebKit::WebScrollbar> scrollbar, WebKit::WebScrollbarThemePainter painter, scoped_ptr<WebKit::WebScrollbarThemeGeometry> geometry, int scrollLayerId)
31 : m_scrollbar(scrollbar.Pass())
32 , m_painter(painter)
33 , m_geometry(geometry.Pass())
34 , m_scrollLayerId(scrollLayerId)
35 , m_textureFormat(GL_INVALID_ENUM)
39 ScrollbarLayer::~ScrollbarLayer()
43 void ScrollbarLayer::setScrollLayerId(int id)
45 if (id == m_scrollLayerId)
46 return;
48 m_scrollLayerId = id;
49 setNeedsFullTreeSync();
52 int ScrollbarLayer::maxTextureSize() {
53 DCHECK(layerTreeHost());
54 return layerTreeHost()->rendererCapabilities().maxTextureSize;
57 float ScrollbarLayer::clampScaleToMaxTextureSize(float scale) {
58 // If the scaled contentBounds() is bigger than the max texture size of the
59 // device, we need to clamp it by rescaling, since contentBounds() is used
60 // below to set the texture size.
61 gfx::Size scaledBounds = computeContentBoundsForScale(scale, scale);
62 if (scaledBounds.width() > maxTextureSize() || scaledBounds.height() > maxTextureSize()) {
63 if (scaledBounds.width() > scaledBounds.height())
64 return (maxTextureSize() - 1) / static_cast<float>(bounds().width());
65 else
66 return (maxTextureSize() - 1) / static_cast<float>(bounds().height());
68 return scale;
71 void ScrollbarLayer::setContentsScale(float contentsScale) {
72 contentsScale = clampScaleToMaxTextureSize(contentsScale);
73 ContentsScalingLayer::setContentsScale(contentsScale);
74 DCHECK_LE(contentBounds().width(), maxTextureSize());
75 DCHECK_LE(contentBounds().height(), maxTextureSize());
78 void ScrollbarLayer::pushPropertiesTo(LayerImpl* layer)
80 ContentsScalingLayer::pushPropertiesTo(layer);
82 ScrollbarLayerImpl* scrollbarLayer = static_cast<ScrollbarLayerImpl*>(layer);
84 if (!scrollbarLayer->scrollbarGeometry())
85 scrollbarLayer->setScrollbarGeometry(ScrollbarGeometryFixedThumb::create(make_scoped_ptr(m_geometry->clone())));
87 scrollbarLayer->setScrollbarData(m_scrollbar.get());
89 if (m_backTrack && m_backTrack->texture()->haveBackingTexture())
90 scrollbarLayer->setBackTrackResourceId(m_backTrack->texture()->resourceId());
91 else
92 scrollbarLayer->setBackTrackResourceId(0);
94 if (m_foreTrack && m_foreTrack->texture()->haveBackingTexture())
95 scrollbarLayer->setForeTrackResourceId(m_foreTrack->texture()->resourceId());
96 else
97 scrollbarLayer->setForeTrackResourceId(0);
99 if (m_thumb && m_thumb->texture()->haveBackingTexture())
100 scrollbarLayer->setThumbResourceId(m_thumb->texture()->resourceId());
101 else
102 scrollbarLayer->setThumbResourceId(0);
105 ScrollbarLayer* ScrollbarLayer::toScrollbarLayer()
107 return this;
110 class ScrollbarBackgroundPainter : public LayerPainter {
111 public:
112 static scoped_ptr<ScrollbarBackgroundPainter> create(WebKit::WebScrollbar* scrollbar, WebKit::WebScrollbarThemePainter painter, WebKit::WebScrollbarThemeGeometry* geometry, WebKit::WebScrollbar::ScrollbarPart trackPart)
114 return make_scoped_ptr(new ScrollbarBackgroundPainter(scrollbar, painter, geometry, trackPart));
117 virtual void paint(SkCanvas* skCanvas, const gfx::Rect& contentRect, gfx::RectF&) OVERRIDE
119 WebKit::WebCanvas* canvas = skCanvas;
120 // The following is a simplification of ScrollbarThemeComposite::paint.
121 m_painter.paintScrollbarBackground(canvas, contentRect);
123 if (m_geometry->hasButtons(m_scrollbar)) {
124 WebRect backButtonStartPaintRect = m_geometry->backButtonStartRect(m_scrollbar);
125 m_painter.paintBackButtonStart(canvas, backButtonStartPaintRect);
127 WebRect backButtonEndPaintRect = m_geometry->backButtonEndRect(m_scrollbar);
128 m_painter.paintBackButtonEnd(canvas, backButtonEndPaintRect);
130 WebRect forwardButtonStartPaintRect = m_geometry->forwardButtonStartRect(m_scrollbar);
131 m_painter.paintForwardButtonStart(canvas, forwardButtonStartPaintRect);
133 WebRect forwardButtonEndPaintRect = m_geometry->forwardButtonEndRect(m_scrollbar);
134 m_painter.paintForwardButtonEnd(canvas, forwardButtonEndPaintRect);
137 WebRect trackPaintRect = m_geometry->trackRect(m_scrollbar);
138 m_painter.paintTrackBackground(canvas, trackPaintRect);
140 bool thumbPresent = m_geometry->hasThumb(m_scrollbar);
141 if (thumbPresent) {
142 if (m_trackPart == WebKit::WebScrollbar::ForwardTrackPart)
143 m_painter.paintForwardTrackPart(canvas, trackPaintRect);
144 else
145 m_painter.paintBackTrackPart(canvas, trackPaintRect);
148 m_painter.paintTickmarks(canvas, trackPaintRect);
150 private:
151 ScrollbarBackgroundPainter(WebKit::WebScrollbar* scrollbar, WebKit::WebScrollbarThemePainter painter, WebKit::WebScrollbarThemeGeometry* geometry, WebKit::WebScrollbar::ScrollbarPart trackPart)
152 : m_scrollbar(scrollbar)
153 , m_painter(painter)
154 , m_geometry(geometry)
155 , m_trackPart(trackPart)
159 WebKit::WebScrollbar* m_scrollbar;
160 WebKit::WebScrollbarThemePainter m_painter;
161 WebKit::WebScrollbarThemeGeometry* m_geometry;
162 WebKit::WebScrollbar::ScrollbarPart m_trackPart;
164 DISALLOW_COPY_AND_ASSIGN(ScrollbarBackgroundPainter);
167 class ScrollbarThumbPainter : public LayerPainter {
168 public:
169 static scoped_ptr<ScrollbarThumbPainter> create(WebKit::WebScrollbar* scrollbar, WebKit::WebScrollbarThemePainter painter, WebKit::WebScrollbarThemeGeometry* geometry)
171 return make_scoped_ptr(new ScrollbarThumbPainter(scrollbar, painter, geometry));
174 virtual void paint(SkCanvas* skCanvas, const gfx::Rect& contentRect, gfx::RectF& opaque) OVERRIDE
176 WebKit::WebCanvas* canvas = skCanvas;
178 // Consider the thumb to be at the origin when painting.
179 WebRect thumbRect = m_geometry->thumbRect(m_scrollbar);
180 thumbRect.x = 0;
181 thumbRect.y = 0;
182 m_painter.paintThumb(canvas, thumbRect);
185 private:
186 ScrollbarThumbPainter(WebKit::WebScrollbar* scrollbar, WebKit::WebScrollbarThemePainter painter, WebKit::WebScrollbarThemeGeometry* geometry)
187 : m_scrollbar(scrollbar)
188 , m_painter(painter)
189 , m_geometry(geometry)
193 WebKit::WebScrollbar* m_scrollbar;
194 WebKit::WebScrollbarThemePainter m_painter;
195 WebKit::WebScrollbarThemeGeometry* m_geometry;
197 DISALLOW_COPY_AND_ASSIGN(ScrollbarThumbPainter);
200 void ScrollbarLayer::setLayerTreeHost(LayerTreeHost* host)
202 if (!host || host != layerTreeHost()) {
203 m_backTrackUpdater = NULL;
204 m_backTrack.reset();
205 m_thumbUpdater = NULL;
206 m_thumb.reset();
209 ContentsScalingLayer::setLayerTreeHost(host);
212 void ScrollbarLayer::createUpdaterIfNeeded()
214 m_textureFormat = layerTreeHost()->rendererCapabilities().bestTextureFormat;
216 if (!m_backTrackUpdater)
217 m_backTrackUpdater = CachingBitmapContentLayerUpdater::Create(ScrollbarBackgroundPainter::create(m_scrollbar.get(), m_painter, m_geometry.get(), WebKit::WebScrollbar::BackTrackPart).PassAs<LayerPainter>());
218 if (!m_backTrack)
219 m_backTrack = m_backTrackUpdater->createResource(layerTreeHost()->contentsTextureManager());
221 // Only create two-part track if we think the two parts could be different in appearance.
222 if (m_scrollbar->isCustomScrollbar()) {
223 if (!m_foreTrackUpdater)
224 m_foreTrackUpdater = CachingBitmapContentLayerUpdater::Create(ScrollbarBackgroundPainter::create(m_scrollbar.get(), m_painter, m_geometry.get(), WebKit::WebScrollbar::ForwardTrackPart).PassAs<LayerPainter>());
225 if (!m_foreTrack)
226 m_foreTrack = m_foreTrackUpdater->createResource(layerTreeHost()->contentsTextureManager());
229 if (!m_thumbUpdater)
230 m_thumbUpdater = CachingBitmapContentLayerUpdater::Create(ScrollbarThumbPainter::create(m_scrollbar.get(), m_painter, m_geometry.get()).PassAs<LayerPainter>());
231 if (!m_thumb)
232 m_thumb = m_thumbUpdater->createResource(layerTreeHost()->contentsTextureManager());
235 void ScrollbarLayer::updatePart(CachingBitmapContentLayerUpdater* painter, LayerUpdater::Resource* texture, const gfx::Rect& rect, ResourceUpdateQueue& queue, RenderingStats& stats)
237 // Skip painting and uploading if there are no invalidations and
238 // we already have valid texture data.
239 if (texture->texture()->haveBackingTexture()
240 && texture->texture()->size() == rect.size()
241 && m_updateRect.IsEmpty())
242 return;
244 // We should always have enough memory for UI.
245 DCHECK(texture->texture()->canAcquireBackingTexture());
246 if (!texture->texture()->canAcquireBackingTexture())
247 return;
249 // Paint and upload the entire part.
250 gfx::Rect paintedOpaqueRect;
251 painter->prepareToUpdate(rect, rect.size(), contentsScaleX(), contentsScaleY(), paintedOpaqueRect, stats);
252 if (!painter->pixelsDidChange() && texture->texture()->haveBackingTexture()) {
253 TRACE_EVENT_INSTANT0("cc","ScrollbarLayer::updatePart no texture upload needed");
254 return;
257 gfx::Vector2d destOffset(0, 0);
258 texture->update(queue, rect, destOffset, false, stats);
261 gfx::Rect ScrollbarLayer::scrollbarLayerRectToContentRect(const gfx::Rect& layerRect) const
263 // Don't intersect with the bounds as in layerRectToContentRect() because
264 // layerRect here might be in coordinates of the containing layer.
265 gfx::RectF contentRect = gfx::ScaleRect(layerRect, contentsScaleX(), contentsScaleY());
266 return gfx::ToEnclosingRect(contentRect);
269 void ScrollbarLayer::setTexturePriorities(const PriorityCalculator&)
271 if (contentBounds().IsEmpty())
272 return;
273 DCHECK_LE(contentBounds().width(), maxTextureSize());
274 DCHECK_LE(contentBounds().height(), maxTextureSize());
276 createUpdaterIfNeeded();
278 bool drawsToRoot = !renderTarget()->parent();
279 if (m_backTrack) {
280 m_backTrack->texture()->setDimensions(contentBounds(), m_textureFormat);
281 m_backTrack->texture()->setRequestPriority(PriorityCalculator::uiPriority(drawsToRoot));
283 if (m_foreTrack) {
284 m_foreTrack->texture()->setDimensions(contentBounds(), m_textureFormat);
285 m_foreTrack->texture()->setRequestPriority(PriorityCalculator::uiPriority(drawsToRoot));
287 if (m_thumb) {
288 gfx::Size thumbSize = scrollbarLayerRectToContentRect(m_geometry->thumbRect(m_scrollbar.get())).size();
289 m_thumb->texture()->setDimensions(thumbSize, m_textureFormat);
290 m_thumb->texture()->setRequestPriority(PriorityCalculator::uiPriority(drawsToRoot));
294 void ScrollbarLayer::update(ResourceUpdateQueue& queue, const OcclusionTracker*, RenderingStats& stats)
296 if (contentBounds().IsEmpty())
297 return;
299 createUpdaterIfNeeded();
301 gfx::Rect contentRect = scrollbarLayerRectToContentRect(gfx::Rect(m_scrollbar->location(), bounds()));
302 updatePart(m_backTrackUpdater.get(), m_backTrack.get(), contentRect, queue, stats);
303 if (m_foreTrack && m_foreTrackUpdater)
304 updatePart(m_foreTrackUpdater.get(), m_foreTrack.get(), contentRect, queue, stats);
306 // Consider the thumb to be at the origin when painting.
307 WebKit::WebRect thumbRect = m_geometry->thumbRect(m_scrollbar.get());
308 gfx::Rect originThumbRect = scrollbarLayerRectToContentRect(gfx::Rect(0, 0, thumbRect.width, thumbRect.height));
309 if (!originThumbRect.IsEmpty())
310 updatePart(m_thumbUpdater.get(), m_thumb.get(), originThumbRect, queue, stats);
313 } // namespace cc