Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 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 #include "core/paint/FramePainter.h" | |
| 7 | |
| 8 #include "core/dom/DocumentMarkerController.h" | |
| 9 #include "core/frame/FrameView.h" | |
| 10 #include "core/inspector/InspectorInstrumentation.h" | |
| 11 #include "core/inspector/InspectorTraceEvents.h" | |
| 12 #include "core/page/Chrome.h" | |
| 13 #include "core/page/ChromeClient.h" | |
| 14 #include "core/page/Page.h" | |
| 15 #include "core/paint/LayerPainter.h" | |
| 16 #include "core/paint/ScrollbarPainter.h" | |
| 17 #include "core/rendering/RenderLayer.h" | |
| 18 #include "core/rendering/RenderView.h" | |
| 19 #include "platform/fonts/FontCache.h" | |
| 20 #include "platform/graphics/GraphicsContext.h" | |
| 21 #include "platform/graphics/GraphicsContextStateSaver.h" | |
| 22 #include "platform/scroll/ScrollbarTheme.h" | |
| 23 | |
| 24 namespace blink { | |
| 25 | |
| 26 bool FramePainter::s_inPaintContents = false; | |
| 27 | |
| 28 void FramePainter::paint(GraphicsContext* context, const IntRect& rect) | |
| 29 { | |
| 30 m_frameView.notifyPageThatContentAreaWillPaint(); | |
| 31 | |
| 32 IntRect documentDirtyRect = rect; | |
| 33 IntRect visibleAreaWithoutScrollbars(m_frameView.location(), m_frameView.vis ibleContentRect().size()); | |
| 34 documentDirtyRect.intersect(visibleAreaWithoutScrollbars); | |
| 35 | |
| 36 if (!documentDirtyRect.isEmpty()) { | |
| 37 GraphicsContextStateSaver stateSaver(*context); | |
| 38 | |
| 39 context->translate(m_frameView.x() - m_frameView.scrollX(), m_frameView. y() - m_frameView.scrollY()); | |
| 40 context->clip(m_frameView.visibleContentRect()); | |
| 41 | |
| 42 documentDirtyRect.moveBy(-m_frameView.location() + m_frameView.scrollPos ition()); | |
| 43 paintContents(context, documentDirtyRect); | |
| 44 } | |
| 45 | |
| 46 calculateAndPaintOverhangAreas(context, rect); | |
| 47 | |
| 48 // Now paint the scrollbars. | |
| 49 if (!m_frameView.scrollbarsSuppressed() && (m_frameView.horizontalScrollbar( ) || m_frameView.verticalScrollbar())) { | |
| 50 GraphicsContextStateSaver stateSaver(*context); | |
| 51 IntRect scrollViewDirtyRect = rect; | |
| 52 IntRect visibleAreaWithScrollbars(m_frameView.location(), m_frameView.vi sibleContentRect(IncludeScrollbars).size()); | |
| 53 scrollViewDirtyRect.intersect(visibleAreaWithScrollbars); | |
| 54 context->translate(m_frameView.x(), m_frameView.y()); | |
| 55 scrollViewDirtyRect.moveBy(-m_frameView.location()); | |
| 56 context->clip(IntRect(IntPoint(), visibleAreaWithScrollbars.size())); | |
| 57 | |
| 58 paintScrollbars(context, scrollViewDirtyRect); | |
| 59 } | |
| 60 | |
| 61 // Paint the panScroll Icon | |
| 62 if (m_frameView.drawPanScrollIcon()) | |
| 63 m_frameView.paintPanScrollIcon(context); | |
| 64 } | |
| 65 | |
| 66 void FramePainter::paintContents(GraphicsContext* p, const IntRect& rect) | |
| 67 { | |
| 68 Document* document = m_frameView.frame().document(); | |
| 69 | |
| 70 #ifndef NDEBUG | |
| 71 bool fillWithRed; | |
| 72 if (document->printing()) | |
| 73 fillWithRed = false; // Printing, don't fill with red (can't remember wh y). | |
| 74 else if (m_frameView.frame().owner()) | |
| 75 fillWithRed = false; // Subframe, don't fill with red. | |
| 76 else if (m_frameView.isTransparent()) | |
| 77 fillWithRed = false; // Transparent, don't fill with red. | |
| 78 else if (m_frameView.paintBehavior() & PaintBehaviorSelectionOnly) | |
| 79 fillWithRed = false; // Selections are transparent, don't fill with red. | |
| 80 else if (m_frameView.nodeToDraw()) | |
| 81 fillWithRed = false; // Element images are transparent, don't fill with red. | |
| 82 else | |
| 83 fillWithRed = true; | |
| 84 | |
| 85 if (fillWithRed) | |
| 86 p->fillRect(rect, Color(0xFF, 0, 0)); | |
| 87 #endif | |
| 88 | |
| 89 RenderView* renderView = m_frameView.renderView(); | |
| 90 if (!renderView) { | |
| 91 WTF_LOG_ERROR("called FramePainter::paint with nil renderer"); | |
| 92 return; | |
| 93 } | |
| 94 | |
| 95 RELEASE_ASSERT(!m_frameView.needsLayout()); | |
| 96 ASSERT(document->lifecycle().state() >= DocumentLifecycle::CompositingClean) ; | |
| 97 | |
| 98 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Paint", "data" , InspectorPaintEvent::data(renderView, rect, 0)); | |
| 99 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), " CallStack", "stack", InspectorCallStackEvent::currentCallStack()); | |
| 100 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli ne migrates to tracing. | |
| 101 InspectorInstrumentation::willPaint(renderView, 0); | |
| 102 | |
| 103 bool isTopLevelPainter = !s_inPaintContents; | |
| 104 s_inPaintContents = true; | |
| 105 | |
| 106 FontCachePurgePreventer fontCachePurgePreventer; | |
| 107 | |
| 108 PaintBehavior oldPaintBehavior = m_frameView.paintBehavior(); | |
| 109 | |
| 110 if (FrameView* parentView = m_frameView.parentFrameView()) { | |
| 111 if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers) | |
| 112 m_frameView.setPaintBehavior(m_frameView.paintBehavior() | PaintBeha viorFlattenCompositingLayers); | |
| 113 } | |
| 114 | |
| 115 if (m_frameView.paintBehavior() == PaintBehaviorNormal) | |
| 116 document->markers().invalidateRenderedRectsForMarkersInRect(rect); | |
| 117 | |
| 118 if (document->printing()) | |
| 119 m_frameView.setPaintBehavior(m_frameView.paintBehavior() | PaintBehavior FlattenCompositingLayers); | |
| 120 | |
| 121 ASSERT(!m_frameView.isPainting()); | |
| 122 m_frameView.setIsPainting(true); | |
| 123 | |
| 124 // m_nodeToDraw is used to draw only one element (and its descendants) | |
|
leviw_travelin_and_unemployed
2014/10/14 22:06:11
s/m_nodeToDraw()/nodeToDraw/?
chrishtr
2014/10/14 22:11:43
Done.
| |
| 125 RenderObject* renderer = m_frameView.nodeToDraw() ? m_frameView.nodeToDraw() ->renderer() : 0; | |
| 126 RenderLayer* rootLayer = renderView->layer(); | |
| 127 | |
| 128 #if ENABLE(ASSERT) | |
| 129 renderView->assertSubtreeIsLaidOut(); | |
| 130 RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(*rootLayer- >renderer()); | |
| 131 #endif | |
| 132 | |
| 133 LayerPainter layerPainter(*rootLayer); | |
| 134 | |
| 135 layerPainter.paint(p, rect, m_frameView.paintBehavior(), renderer); | |
| 136 | |
| 137 if (rootLayer->containsDirtyOverlayScrollbars()) | |
| 138 layerPainter.paintOverlayScrollbars(p, rect, m_frameView.paintBehavior() , renderer); | |
| 139 | |
| 140 m_frameView.setIsPainting(false); | |
| 141 | |
| 142 m_frameView.setPaintBehavior(oldPaintBehavior); | |
| 143 m_frameView.setLastPaintTime(currentTime()); | |
| 144 | |
| 145 // Regions may have changed as a result of the visibility/z-index of element changing. | |
| 146 if (document->annotatedRegionsDirty()) | |
| 147 m_frameView.updateAnnotatedRegions(); | |
| 148 | |
| 149 if (isTopLevelPainter) { | |
| 150 // Everything that happens after paintContents completions is considered | |
| 151 // to be part of the next frame. | |
| 152 m_frameView.setCurrentFrameTimeStamp(currentTime()); | |
|
leviw_travelin_and_unemployed
2014/10/14 22:06:11
This is kinda funky, but alright.
chrishtr
2014/10/14 22:11:43
Yeah.
| |
| 153 s_inPaintContents = false; | |
| 154 } | |
| 155 | |
| 156 InspectorInstrumentation::didPaint(renderView, 0, p, rect); | |
| 157 } | |
| 158 | |
| 159 void FramePainter::paintScrollbars(GraphicsContext* context, const IntRect& rect ) | |
| 160 { | |
| 161 if (m_frameView.horizontalScrollbar() && !m_frameView.layerForHorizontalScro llbar()) | |
| 162 paintScrollbar(context, m_frameView.horizontalScrollbar(), rect); | |
| 163 if (m_frameView.verticalScrollbar() && !m_frameView.layerForVerticalScrollba r()) | |
| 164 paintScrollbar(context, m_frameView.verticalScrollbar(), rect); | |
| 165 | |
| 166 if (m_frameView.layerForScrollCorner()) | |
| 167 return; | |
| 168 paintScrollCorner(context, m_frameView.scrollCornerRect()); | |
| 169 } | |
| 170 | |
| 171 void FramePainter::paintScrollCorner(GraphicsContext* context, const IntRect& co rnerRect) | |
| 172 { | |
| 173 if (m_frameView.scrollCorner()) { | |
| 174 bool needsBackground = m_frameView.frame().isMainFrame(); | |
| 175 if (needsBackground) | |
| 176 context->fillRect(cornerRect, m_frameView.baseBackgroundColor()); | |
| 177 ScrollbarPainter::paintIntoRect(m_frameView.scrollCorner(), context, cor nerRect.location(), cornerRect); | |
| 178 return; | |
| 179 } | |
| 180 | |
| 181 ScrollbarTheme::theme()->paintScrollCorner(context, cornerRect); | |
| 182 } | |
| 183 | |
| 184 void FramePainter::paintScrollbar(GraphicsContext* context, Scrollbar* bar, cons t IntRect& rect) | |
| 185 { | |
| 186 bool needsBackground = bar->isCustomScrollbar() && m_frameView.frame().isMai nFrame(); | |
| 187 if (needsBackground) { | |
| 188 IntRect toFill = bar->frameRect(); | |
| 189 toFill.intersect(rect); | |
| 190 context->fillRect(toFill, m_frameView.baseBackgroundColor()); | |
| 191 } | |
| 192 | |
| 193 bar->paint(context, rect); | |
| 194 } | |
| 195 | |
| 196 void FramePainter::paintOverhangAreas(GraphicsContext* context, const IntRect& h orizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirty Rect) | |
| 197 { | |
| 198 if (m_frameView.frame().document()->printing()) | |
| 199 return; | |
| 200 | |
| 201 if (m_frameView.frame().isMainFrame()) { | |
| 202 if (m_frameView.frame().page()->chrome().client().paintCustomOverhangAre a(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect)) | |
| 203 return; | |
| 204 } | |
| 205 | |
| 206 paintOverhangAreasInternal(context, horizontalOverhangArea, verticalOverhang Area, dirtyRect); | |
| 207 } | |
| 208 | |
| 209 void FramePainter::paintOverhangAreasInternal(GraphicsContext* context, const In tRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRec t& dirtyRect) | |
| 210 { | |
| 211 ScrollbarTheme::theme()->paintOverhangBackground(context, horizontalOverhang Rect, verticalOverhangRect, dirtyRect); | |
| 212 ScrollbarTheme::theme()->paintOverhangShadows(context, m_frameView.scrollOff set(), horizontalOverhangRect, verticalOverhangRect, dirtyRect); | |
| 213 } | |
| 214 | |
| 215 void FramePainter::calculateAndPaintOverhangAreas(GraphicsContext* context, cons t IntRect& dirtyRect) | |
| 216 { | |
| 217 IntRect horizontalOverhangRect; | |
| 218 IntRect verticalOverhangRect; | |
| 219 m_frameView.calculateOverhangAreasForPainting(horizontalOverhangRect, vertic alOverhangRect); | |
| 220 | |
| 221 if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(ver ticalOverhangRect)) | |
| 222 paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect , dirtyRect); | |
| 223 } | |
| 224 | |
| 225 } // namespace blink | |
| OLD | NEW |