In iossim, ignore harmless messages from launchd.
[chromium-blink-merge.git] / cc / scrollbar_layer.cc
blobc6ca1b1d2f32bb037047efdaa07f7a9d243f7a05
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 "third_party/WebKit/Source/Platform/chromium/public/WebRect.h"
14 #include "ui/gfx/rect_conversions.h"
16 namespace cc {
18 scoped_ptr<LayerImpl> ScrollbarLayer::createLayerImpl(LayerTreeImpl* treeImpl)
20 return ScrollbarLayerImpl::create(treeImpl, id()).PassAs<LayerImpl>();
23 scoped_refptr<ScrollbarLayer> ScrollbarLayer::create(
24 scoped_ptr<WebKit::WebScrollbar> scrollbar,
25 scoped_ptr<ScrollbarThemePainter> painter,
26 scoped_ptr<WebKit::WebScrollbarThemeGeometry> geometry,
27 int scrollLayerId)
29 return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(), painter.Pass(), geometry.Pass(), scrollLayerId));
32 ScrollbarLayer::ScrollbarLayer(
33 scoped_ptr<WebKit::WebScrollbar> scrollbar,
34 scoped_ptr<ScrollbarThemePainter> painter,
35 scoped_ptr<WebKit::WebScrollbarThemeGeometry> geometry,
36 int scrollLayerId)
37 : m_scrollbar(scrollbar.Pass())
38 , m_painter(painter.Pass())
39 , m_geometry(geometry.Pass())
40 , m_scrollLayerId(scrollLayerId)
41 , m_textureFormat(GL_INVALID_ENUM)
43 if (!m_scrollbar->isOverlay())
44 setShouldScrollOnMainThread(true);
47 ScrollbarLayer::~ScrollbarLayer()
51 void ScrollbarLayer::setScrollLayerId(int id)
53 if (id == m_scrollLayerId)
54 return;
56 m_scrollLayerId = id;
57 setNeedsFullTreeSync();
60 int ScrollbarLayer::maxTextureSize() {
61 DCHECK(layerTreeHost());
62 return layerTreeHost()->rendererCapabilities().maxTextureSize;
65 float ScrollbarLayer::clampScaleToMaxTextureSize(float scale) {
66 // If the scaled contentBounds() is bigger than the max texture size of the
67 // device, we need to clamp it by rescaling, since contentBounds() is used
68 // below to set the texture size.
69 gfx::Size scaledBounds = computeContentBoundsForScale(scale, scale);
70 if (scaledBounds.width() > maxTextureSize() || scaledBounds.height() > maxTextureSize()) {
71 if (scaledBounds.width() > scaledBounds.height())
72 return (maxTextureSize() - 1) / static_cast<float>(bounds().width());
73 else
74 return (maxTextureSize() - 1) / static_cast<float>(bounds().height());
76 return scale;
79 void ScrollbarLayer::calculateContentsScale(
80 float idealContentsScale,
81 float* contentsScaleX,
82 float* contentsScaleY,
83 gfx::Size* contentBounds)
85 ContentsScalingLayer::calculateContentsScale(
86 clampScaleToMaxTextureSize(idealContentsScale),
87 contentsScaleX,
88 contentsScaleY,
89 contentBounds);
90 DCHECK_LE(contentBounds->width(), maxTextureSize());
91 DCHECK_LE(contentBounds->height(), maxTextureSize());
94 void ScrollbarLayer::pushPropertiesTo(LayerImpl* layer)
96 ContentsScalingLayer::pushPropertiesTo(layer);
98 ScrollbarLayerImpl* scrollbarLayer = static_cast<ScrollbarLayerImpl*>(layer);
100 if (!scrollbarLayer->scrollbarGeometry())
101 scrollbarLayer->setScrollbarGeometry(ScrollbarGeometryFixedThumb::create(make_scoped_ptr(m_geometry->clone())));
103 scrollbarLayer->setScrollbarData(m_scrollbar.get());
105 if (m_backTrack && m_backTrack->texture()->haveBackingTexture())
106 scrollbarLayer->setBackTrackResourceId(m_backTrack->texture()->resourceId());
107 else
108 scrollbarLayer->setBackTrackResourceId(0);
110 if (m_foreTrack && m_foreTrack->texture()->haveBackingTexture())
111 scrollbarLayer->setForeTrackResourceId(m_foreTrack->texture()->resourceId());
112 else
113 scrollbarLayer->setForeTrackResourceId(0);
115 if (m_thumb && m_thumb->texture()->haveBackingTexture())
116 scrollbarLayer->setThumbResourceId(m_thumb->texture()->resourceId());
117 else
118 scrollbarLayer->setThumbResourceId(0);
121 ScrollbarLayer* ScrollbarLayer::toScrollbarLayer()
123 return this;
126 class ScrollbarBackgroundPainter : public LayerPainter {
127 public:
128 static scoped_ptr<ScrollbarBackgroundPainter> create(WebKit::WebScrollbar* scrollbar, ScrollbarThemePainter *painter, WebKit::WebScrollbarThemeGeometry* geometry, WebKit::WebScrollbar::ScrollbarPart trackPart)
130 return make_scoped_ptr(new ScrollbarBackgroundPainter(scrollbar, painter, geometry, trackPart));
133 virtual void paint(SkCanvas* canvas, gfx::Rect contentRect, gfx::RectF&) OVERRIDE
135 // The following is a simplification of ScrollbarThemeComposite::paint.
136 m_painter->PaintScrollbarBackground(canvas, contentRect);
138 if (m_geometry->hasButtons(m_scrollbar)) {
139 gfx::Rect backButtonStartPaintRect = m_geometry->backButtonStartRect(m_scrollbar);
140 m_painter->PaintBackButtonStart(canvas, backButtonStartPaintRect);
142 gfx::Rect backButtonEndPaintRect = m_geometry->backButtonEndRect(m_scrollbar);
143 m_painter->PaintBackButtonEnd(canvas, backButtonEndPaintRect);
145 gfx::Rect forwardButtonStartPaintRect = m_geometry->forwardButtonStartRect(m_scrollbar);
146 m_painter->PaintForwardButtonStart(canvas, forwardButtonStartPaintRect);
148 gfx::Rect forwardButtonEndPaintRect = m_geometry->forwardButtonEndRect(m_scrollbar);
149 m_painter->PaintForwardButtonEnd(canvas, forwardButtonEndPaintRect);
152 gfx::Rect trackPaintRect = m_geometry->trackRect(m_scrollbar);
153 m_painter->PaintTrackBackground(canvas, trackPaintRect);
155 bool thumbPresent = m_geometry->hasThumb(m_scrollbar);
156 if (thumbPresent) {
157 if (m_trackPart == WebKit::WebScrollbar::ForwardTrackPart)
158 m_painter->PaintForwardTrackPart(canvas, trackPaintRect);
159 else
160 m_painter->PaintBackTrackPart(canvas, trackPaintRect);
163 m_painter->PaintTickmarks(canvas, trackPaintRect);
165 private:
166 ScrollbarBackgroundPainter(WebKit::WebScrollbar* scrollbar, ScrollbarThemePainter *painter, WebKit::WebScrollbarThemeGeometry* geometry, WebKit::WebScrollbar::ScrollbarPart trackPart)
167 : m_scrollbar(scrollbar)
168 , m_painter(painter)
169 , m_geometry(geometry)
170 , m_trackPart(trackPart)
174 WebKit::WebScrollbar* m_scrollbar;
175 ScrollbarThemePainter* m_painter;
176 WebKit::WebScrollbarThemeGeometry* m_geometry;
177 WebKit::WebScrollbar::ScrollbarPart m_trackPart;
179 DISALLOW_COPY_AND_ASSIGN(ScrollbarBackgroundPainter);
182 class ScrollbarThumbPainter : public LayerPainter {
183 public:
184 static scoped_ptr<ScrollbarThumbPainter> create(WebKit::WebScrollbar* scrollbar, ScrollbarThemePainter* painter, WebKit::WebScrollbarThemeGeometry* geometry)
186 return make_scoped_ptr(new ScrollbarThumbPainter(scrollbar, painter, geometry));
189 virtual void paint(SkCanvas* canvas, gfx::Rect contentRect, gfx::RectF& opaque) OVERRIDE
191 // Consider the thumb to be at the origin when painting.
192 gfx::Rect thumbRect = m_geometry->thumbRect(m_scrollbar);
193 m_painter->PaintThumb(canvas, gfx::Rect(thumbRect.size()));
196 private:
197 ScrollbarThumbPainter(WebKit::WebScrollbar* scrollbar, ScrollbarThemePainter* painter, WebKit::WebScrollbarThemeGeometry* geometry)
198 : m_scrollbar(scrollbar)
199 , m_painter(painter)
200 , m_geometry(geometry)
204 WebKit::WebScrollbar* m_scrollbar;
205 ScrollbarThemePainter* m_painter;
206 WebKit::WebScrollbarThemeGeometry* m_geometry;
208 DISALLOW_COPY_AND_ASSIGN(ScrollbarThumbPainter);
211 void ScrollbarLayer::setLayerTreeHost(LayerTreeHost* host)
213 if (!host || host != layerTreeHost()) {
214 m_backTrackUpdater = NULL;
215 m_backTrack.reset();
216 m_thumbUpdater = NULL;
217 m_thumb.reset();
220 ContentsScalingLayer::setLayerTreeHost(host);
223 void ScrollbarLayer::createUpdaterIfNeeded()
225 m_textureFormat = layerTreeHost()->rendererCapabilities().bestTextureFormat;
227 if (!m_backTrackUpdater)
228 m_backTrackUpdater = CachingBitmapContentLayerUpdater::Create(ScrollbarBackgroundPainter::create(m_scrollbar.get(), m_painter.get(), m_geometry.get(), WebKit::WebScrollbar::BackTrackPart).PassAs<LayerPainter>());
229 if (!m_backTrack)
230 m_backTrack = m_backTrackUpdater->createResource(layerTreeHost()->contentsTextureManager());
232 // Only create two-part track if we think the two parts could be different in appearance.
233 if (m_scrollbar->isCustomScrollbar()) {
234 if (!m_foreTrackUpdater)
235 m_foreTrackUpdater = CachingBitmapContentLayerUpdater::Create(ScrollbarBackgroundPainter::create(m_scrollbar.get(), m_painter.get(), m_geometry.get(), WebKit::WebScrollbar::ForwardTrackPart).PassAs<LayerPainter>());
236 if (!m_foreTrack)
237 m_foreTrack = m_foreTrackUpdater->createResource(layerTreeHost()->contentsTextureManager());
240 if (!m_thumbUpdater)
241 m_thumbUpdater = CachingBitmapContentLayerUpdater::Create(ScrollbarThumbPainter::create(m_scrollbar.get(), m_painter.get(), m_geometry.get()).PassAs<LayerPainter>());
242 if (!m_thumb)
243 m_thumb = m_thumbUpdater->createResource(layerTreeHost()->contentsTextureManager());
246 void ScrollbarLayer::updatePart(CachingBitmapContentLayerUpdater* painter, LayerUpdater::Resource* resource, const gfx::Rect& rect, ResourceUpdateQueue& queue, RenderingStats& stats)
248 // Skip painting and uploading if there are no invalidations and
249 // we already have valid texture data.
250 if (resource->texture()->haveBackingTexture() &&
251 resource->texture()->size() == rect.size() &&
252 !isDirty())
253 return;
255 // We should always have enough memory for UI.
256 DCHECK(resource->texture()->canAcquireBackingTexture());
257 if (!resource->texture()->canAcquireBackingTexture())
258 return;
260 // Paint and upload the entire part.
261 gfx::Rect paintedOpaqueRect;
262 painter->prepareToUpdate(rect, rect.size(), contentsScaleX(), contentsScaleY(), paintedOpaqueRect, stats);
263 if (!painter->pixelsDidChange() && resource->texture()->haveBackingTexture()) {
264 TRACE_EVENT_INSTANT0("cc","ScrollbarLayer::updatePart no texture upload needed");
265 return;
268 bool partialUpdatesAllowed = layerTreeHost()->settings().maxPartialTextureUpdates > 0;
269 if (!partialUpdatesAllowed)
270 resource->texture()->returnBackingTexture();
272 gfx::Vector2d destOffset(0, 0);
273 resource->update(queue, rect, destOffset, partialUpdatesAllowed, stats);
276 gfx::Rect ScrollbarLayer::scrollbarLayerRectToContentRect(const gfx::Rect& layerRect) const
278 // Don't intersect with the bounds as in layerRectToContentRect() because
279 // layerRect here might be in coordinates of the containing layer.
280 gfx::RectF contentRect = gfx::ScaleRect(layerRect, contentsScaleX(), contentsScaleY());
281 return gfx::ToEnclosingRect(contentRect);
284 void ScrollbarLayer::setTexturePriorities(const PriorityCalculator&)
286 if (contentBounds().IsEmpty())
287 return;
288 DCHECK_LE(contentBounds().width(), maxTextureSize());
289 DCHECK_LE(contentBounds().height(), maxTextureSize());
291 createUpdaterIfNeeded();
293 bool drawsToRoot = !renderTarget()->parent();
294 if (m_backTrack) {
295 m_backTrack->texture()->setDimensions(contentBounds(), m_textureFormat);
296 m_backTrack->texture()->setRequestPriority(PriorityCalculator::uiPriority(drawsToRoot));
298 if (m_foreTrack) {
299 m_foreTrack->texture()->setDimensions(contentBounds(), m_textureFormat);
300 m_foreTrack->texture()->setRequestPriority(PriorityCalculator::uiPriority(drawsToRoot));
302 if (m_thumb) {
303 gfx::Size thumbSize = scrollbarLayerRectToContentRect(m_geometry->thumbRect(m_scrollbar.get())).size();
304 m_thumb->texture()->setDimensions(thumbSize, m_textureFormat);
305 m_thumb->texture()->setRequestPriority(PriorityCalculator::uiPriority(drawsToRoot));
309 void ScrollbarLayer::update(ResourceUpdateQueue& queue, const OcclusionTracker* occlusion, RenderingStats& stats)
311 ContentsScalingLayer::update(queue, occlusion, stats);
313 m_dirtyRect.Union(m_updateRect);
314 if (contentBounds().IsEmpty())
315 return;
316 if (visibleContentRect().IsEmpty())
317 return;
318 if (!isDirty())
319 return;
321 createUpdaterIfNeeded();
323 gfx::Rect contentRect = scrollbarLayerRectToContentRect(gfx::Rect(m_scrollbar->location(), bounds()));
324 updatePart(m_backTrackUpdater.get(), m_backTrack.get(), contentRect, queue, stats);
325 if (m_foreTrack && m_foreTrackUpdater)
326 updatePart(m_foreTrackUpdater.get(), m_foreTrack.get(), contentRect, queue, stats);
328 // Consider the thumb to be at the origin when painting.
329 gfx::Rect thumbRect = m_geometry->thumbRect(m_scrollbar.get());
330 gfx::Rect originThumbRect = scrollbarLayerRectToContentRect(gfx::Rect(thumbRect.size()));
331 if (!originThumbRect.IsEmpty())
332 updatePart(m_thumbUpdater.get(), m_thumb.get(), originThumbRect, queue, stats);
334 m_dirtyRect = gfx::RectF();
337 } // namespace cc