[Win] Tiled drawing is rendering more times than it should
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Sep 2015 19:56:34 +0000 (19:56 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Sep 2015 19:56:34 +0000 (19:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=149144
<rdar://problem/22313905>

Reviewed by Simon Fraser.

Provide a more faithful implemenation of the Objective C tiled drawing logic.
(1) Create a new WebTiledBackingLayerWin class that represents a the
    container of tiles. This matches the Objective C design.
(2) Move implementation of several methods (e.g., isOpaque) to the internal
    class implementation so that the Tile Drawing logic can perform special
    handling in these cases.
(3) Remove the duplicated Tiled Drawing logic from PlatformCALayerWinInternal,
    since it was just duplicating code in TileController and TileGrid.
(4) Clean up the display callback code to avoid performing incorrect flipping
    of the coordinate system.

* PlatformAppleWin.cmake: Add new WebTiledBackingLayerWin file.
* WebCore.vcxproj/WebCore.vcxproj: Add the new WebTiledBackingLayerWin files.
* WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
* platform/graphics/ca/PlatformCALayer.cpp:
(PlatformCALayer::flipContext): Added convenience method.
(PlatformCALayer::drawRepaintIndicator): Ditto.
* platform/graphics/ca/TileGrid.cpp:
(TileGrid::platformCALayerPaintContents): Flip the context before drawing the repaint
indicator on Windows.
* platform/graphics/ca/win/PlatformCALayerWin.cpp:
(PlatformCALayerWin::PlatformCALayerWin): Create a WebTiledBackingLayerWin
object if using tiled drawing.
(PlatformCALayerWin::~PlatformCALayerWin):
(PlatformCALayerWin::isOpaque): Move implementation to internal class.
(PlatformCALayerWin::setOpaque): Ditto.
(PlatformCALayerWin::setBorderWidth): Ditto.
(PlatformCALayerWin::setBorderColor): Ditto.
(PlatformCALayerWin::contentsScale): Ditto.
(PlatformCALayerWin::setContentsScale): Ditto.
(PlatformCALayerWin::cornerRadius): Ditto.
(PlatformCALayerWin::tiledBacking): Ditto.
(PlatformCALayerWin::drawTextAtPoint): New helper method to draw repaint counter
text. Needed to work around bug in CG.
* platform/graphics/ca/win/PlatformCALayerWinInternal.cpp:
(PlatformCALayerWinInternal::PlatformCALayerWinInternal): Remove tiling-logic
related member variables.
(PlatformCALayerWinInternal::~PlatformCALayerWinInternal):
(shouldInvertBeforeDrawingContent): Added convenience method.
(shouldInvertBeforeDrawingRepaintCounters): Ditto.
(PlatformCALayerWinInternal::displayCallback):
(PlatformCALayerWinInternal::drawRepaintCounters): Helper method to
share code between the two layer classes.
(PlatformCALayerWinInternal::internalSetNeedsDisplay): use nullptr.
(PlatformCALayerWinInternal::setNeedsDisplay): Ditto.
(PlatformCALayerWinInternal::setNeedsDisplayInRect): Move tiled code
to WebTiledBackingLayerWin and simplify the remaing code.
(PlatformCALayerWinInternal::setSublayers): Remove tile code.
(PlatformCALayerWinInternal::getSublayers): Ditto.
(PlatformCALayerWinInternal::removeAllSublayers): Ditto.
(PlatformCALayerWinInternal::insertSublayer): Ditto.
(PlatformCALayerWinInternal::sublayerCount): Ditto.
(PlatformCALayerWinInternal::indexOfSublayer): Ditto.
(PlatformCALayerWinInternal::sublayerAtIndex): Ditto.
(PlatformCALayerWinInternal::setBounds): Ditto.
(PlatformCALayerWinInternal::setFrame): Ditto.
(PlatformCALayerWinInternal::isOpaque): Ditto.
(PlatformCALayerWinInternal::setOpaque): Ditto.
(PlatformCALayerWinInternal::contentsScale): Ditto.
(PlatformCALayerWinInternal::setContentsScale): Ditto.
(PlatformCALayerWinInternal::setBorderWidth): Ditto.
(PlatformCALayerWinInternal::setBorderColor): Ditto.
(layerTypeIsTiled): Deleted.
(PlatformCALayerWinInternal::constrainedSize): Deleted.
(PlatformCALayerWinInternal::tileDisplayCallback): Deleted.
(PlatformCALayerWinInternal::addTile): Deleted.
(PlatformCALayerWinInternal::removeTile): Deleted.
(PlatformCALayerWinInternal::tileAtIndex): Deleted.
(PlatformCALayerWinInternal::tileCount): Deleted.
(PlatformCALayerWinInternal::updateTiles): Deleted.
(PlatformCALayerWinInternal::drawTile): Deleted.
(PlatformCALayerWinInternal::createTileController): Deleted.
(PlatformCALayerWinInternal::tiledBacking): Deleted.
* platform/graphics/ca/win/PlatformCALayerWinInternal.h:
(WebCore::PlatformCALayerWinInternal::owner):
* platform/graphics/ca/win/WebTiledBackingLayerWin.cpp: Added.
(WebTiledBackingLayerWin::WebTiledBackingLayerWin):
(WebTiledBackingLayerWin::~WebTiledBackingLayerWin):
(DisplayOnMainThreadContext::DisplayOnMainThreadContext):
(redispatchOnMainQueue):
(WebTiledBackingLayerWin::displayCallback):
(WebTiledBackingLayerWin::setNeedsDisplay):
(WebTiledBackingLayerWin::setNeedsDisplayInRect):
(WebTiledBackingLayerWin::setBounds):
(WebTiledBackingLayerWin::isOpaque):
(WebTiledBackingLayerWin::setOpaque):
(WebTiledBackingLayerWin::contentsScale):
(WebTiledBackingLayerWin::setContentsScale):
(WebTiledBackingLayerWin::setBorderWidth):
(WebTiledBackingLayerWin::setBorderColor):
(WebTiledBackingLayerWin::createTileController):
(WebTiledBackingLayerWin::tiledBacking):
(WebTiledBackingLayerWin::invalidate):
* platform/graphics/ca/win/WebTiledBackingLayerWin.h: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189821 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/PlatformAppleWin.cmake
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/platform/graphics/ca/PlatformCALayer.cpp
Source/WebCore/platform/graphics/ca/PlatformCALayer.h
Source/WebCore/platform/graphics/ca/TileGrid.cpp
Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.h
Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp
Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h
Source/WebCore/platform/graphics/ca/win/WebTiledBackingLayerWin.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/ca/win/WebTiledBackingLayerWin.h [new file with mode: 0644]

index c4d5d1e..d678b0e 100644 (file)
@@ -1,3 +1,106 @@
+2015-09-15  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Tiled drawing is rendering more times than it should
+        https://bugs.webkit.org/show_bug.cgi?id=149144
+        <rdar://problem/22313905>
+
+        Reviewed by Simon Fraser.
+
+        Provide a more faithful implemenation of the Objective C tiled drawing logic.
+        (1) Create a new WebTiledBackingLayerWin class that represents a the
+            container of tiles. This matches the Objective C design.
+        (2) Move implementation of several methods (e.g., isOpaque) to the internal
+            class implementation so that the Tile Drawing logic can perform special
+            handling in these cases.
+        (3) Remove the duplicated Tiled Drawing logic from PlatformCALayerWinInternal,
+            since it was just duplicating code in TileController and TileGrid.
+        (4) Clean up the display callback code to avoid performing incorrect flipping
+            of the coordinate system.
+
+        * PlatformAppleWin.cmake: Add new WebTiledBackingLayerWin file.            
+        * WebCore.vcxproj/WebCore.vcxproj: Add the new WebTiledBackingLayerWin files.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * platform/graphics/ca/PlatformCALayer.cpp:
+        (PlatformCALayer::flipContext): Added convenience method.
+        (PlatformCALayer::drawRepaintIndicator): Ditto.
+        * platform/graphics/ca/TileGrid.cpp:
+        (TileGrid::platformCALayerPaintContents): Flip the context before drawing the repaint
+        indicator on Windows.
+        * platform/graphics/ca/win/PlatformCALayerWin.cpp:
+        (PlatformCALayerWin::PlatformCALayerWin): Create a WebTiledBackingLayerWin
+        object if using tiled drawing.
+        (PlatformCALayerWin::~PlatformCALayerWin):
+        (PlatformCALayerWin::isOpaque): Move implementation to internal class.
+        (PlatformCALayerWin::setOpaque): Ditto.
+        (PlatformCALayerWin::setBorderWidth): Ditto.
+        (PlatformCALayerWin::setBorderColor): Ditto.
+        (PlatformCALayerWin::contentsScale): Ditto.
+        (PlatformCALayerWin::setContentsScale): Ditto.
+        (PlatformCALayerWin::cornerRadius): Ditto.
+        (PlatformCALayerWin::tiledBacking): Ditto.
+        (PlatformCALayerWin::drawTextAtPoint): New helper method to draw repaint counter
+        text. Needed to work around bug in CG.
+        * platform/graphics/ca/win/PlatformCALayerWinInternal.cpp:
+        (PlatformCALayerWinInternal::PlatformCALayerWinInternal): Remove tiling-logic
+        related member variables.
+        (PlatformCALayerWinInternal::~PlatformCALayerWinInternal):
+        (shouldInvertBeforeDrawingContent): Added convenience method.
+        (shouldInvertBeforeDrawingRepaintCounters): Ditto.
+        (PlatformCALayerWinInternal::displayCallback):
+        (PlatformCALayerWinInternal::drawRepaintCounters): Helper method to
+        share code between the two layer classes.
+        (PlatformCALayerWinInternal::internalSetNeedsDisplay): use nullptr.
+        (PlatformCALayerWinInternal::setNeedsDisplay): Ditto.
+        (PlatformCALayerWinInternal::setNeedsDisplayInRect): Move tiled code
+        to WebTiledBackingLayerWin and simplify the remaing code.
+        (PlatformCALayerWinInternal::setSublayers): Remove tile code.
+        (PlatformCALayerWinInternal::getSublayers): Ditto.
+        (PlatformCALayerWinInternal::removeAllSublayers): Ditto.
+        (PlatformCALayerWinInternal::insertSublayer): Ditto.
+        (PlatformCALayerWinInternal::sublayerCount): Ditto.
+        (PlatformCALayerWinInternal::indexOfSublayer): Ditto.
+        (PlatformCALayerWinInternal::sublayerAtIndex): Ditto.
+        (PlatformCALayerWinInternal::setBounds): Ditto.
+        (PlatformCALayerWinInternal::setFrame): Ditto.
+        (PlatformCALayerWinInternal::isOpaque): Ditto.
+        (PlatformCALayerWinInternal::setOpaque): Ditto.
+        (PlatformCALayerWinInternal::contentsScale): Ditto.
+        (PlatformCALayerWinInternal::setContentsScale): Ditto.
+        (PlatformCALayerWinInternal::setBorderWidth): Ditto.
+        (PlatformCALayerWinInternal::setBorderColor): Ditto.
+        (layerTypeIsTiled): Deleted.
+        (PlatformCALayerWinInternal::constrainedSize): Deleted.
+        (PlatformCALayerWinInternal::tileDisplayCallback): Deleted.
+        (PlatformCALayerWinInternal::addTile): Deleted.
+        (PlatformCALayerWinInternal::removeTile): Deleted.
+        (PlatformCALayerWinInternal::tileAtIndex): Deleted.
+        (PlatformCALayerWinInternal::tileCount): Deleted.
+        (PlatformCALayerWinInternal::updateTiles): Deleted.
+        (PlatformCALayerWinInternal::drawTile): Deleted.
+        (PlatformCALayerWinInternal::createTileController): Deleted.
+        (PlatformCALayerWinInternal::tiledBacking): Deleted.
+        * platform/graphics/ca/win/PlatformCALayerWinInternal.h:
+        (WebCore::PlatformCALayerWinInternal::owner):
+        * platform/graphics/ca/win/WebTiledBackingLayerWin.cpp: Added.
+        (WebTiledBackingLayerWin::WebTiledBackingLayerWin):
+        (WebTiledBackingLayerWin::~WebTiledBackingLayerWin):
+        (DisplayOnMainThreadContext::DisplayOnMainThreadContext):
+        (redispatchOnMainQueue):
+        (WebTiledBackingLayerWin::displayCallback):
+        (WebTiledBackingLayerWin::setNeedsDisplay):
+        (WebTiledBackingLayerWin::setNeedsDisplayInRect):
+        (WebTiledBackingLayerWin::setBounds):
+        (WebTiledBackingLayerWin::isOpaque):
+        (WebTiledBackingLayerWin::setOpaque):
+        (WebTiledBackingLayerWin::contentsScale):
+        (WebTiledBackingLayerWin::setContentsScale):
+        (WebTiledBackingLayerWin::setBorderWidth):
+        (WebTiledBackingLayerWin::setBorderColor):
+        (WebTiledBackingLayerWin::createTileController):
+        (WebTiledBackingLayerWin::tiledBacking):
+        (WebTiledBackingLayerWin::invalidate):
+        * platform/graphics/ca/win/WebTiledBackingLayerWin.h: Added.
+
 2015-09-14  David Hyatt  <hyatt@apple.com>
 
         [New Block-Inside-Inline Model] Implement margin collapsing across contiguous anonymous inline blocks.
index 347a49f..8ae0f37 100644 (file)
@@ -49,6 +49,7 @@ list(APPEND WebCore_SOURCES
     platform/graphics/ca/win/PlatformCAFiltersWin.cpp
     platform/graphics/ca/win/PlatformCALayerWin.cpp
     platform/graphics/ca/win/PlatformCALayerWinInternal.cpp
+    platform/graphics/ca/win/WebTiledBackingLayerWin.cpp
     platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp
 
     platform/graphics/cg/BitmapImageCG.cpp
index d31cbf2..0733a4f 100644 (file)
     <ClCompile Include="..\platform\FileSystem.cpp" />
     <ClCompile Include="..\platform\graphics\avfoundation\cf\CDMSessionAVFoundationCF.cpp" />
     <ClCompile Include="..\platform\graphics\avfoundation\cf\WebCoreAVCFResourceLoader.cpp" />
+    <ClCompile Include="..\platform\graphics\ca\win\WebTiledBackingLayerWin.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\platform\graphics\ISOVTTCue.cpp" />
     <ClCompile Include="..\platform\audio\AudioSession.cpp" />
     <ClCompile Include="..\platform\audio\PlatformMediaSession.cpp" />
     </ClInclude>
     <ClInclude Include="..\platform\graphics\ca\win\PlatformCAAnimationWin.h" />
     <ClInclude Include="..\platform\graphics\ca\win\PlatformCALayerWin.h" />
+    <ClInclude Include="..\platform\graphics\ca\win\WebTiledBackingLayerWin.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\platform\graphics\GLContext.h" />
     <ClInclude Include="..\platform\graphics\GraphicsContext3DPrivate.h" />
     <ClInclude Include="..\platform\graphics\cg\SubimageCacheWithTimer.h">
   <ImportGroup Label="ExtensionTargets">
     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
index 175a939..884e1e2 100644 (file)
     <ClCompile Include="..\dom\ChildNodeList.cpp">
       <Filter>dom</Filter>
     </ClCompile>
-    <ClCompile Include="..\dom\ClassNodeList.cpp">
-      <Filter>dom</Filter>
-    </ClCompile>
     <ClCompile Include="..\dom\ClientRect.cpp">
       <Filter>dom</Filter>
     </ClCompile>
     <ClCompile Include="..\dom\Node.cpp">
       <Filter>dom</Filter>
     </ClCompile>
-    <ClCompile Include="..\dom\NodeFilter.cpp">
-      <Filter>dom</Filter>
-    </ClCompile>
     <ClCompile Include="..\dom\NodeFilterCondition.cpp">
       <Filter>dom</Filter>
     </ClCompile>
     <ClCompile Include="..\page\DOMSecurityPolicy.cpp">
       <Filter>page</Filter>
     </ClCompile>
+    <ClCompile Include="..\platform\network\DataURLDecoder.cpp" />
+    <ClCompile Include="..\dom\ClassCollection.cpp" />
+    <ClCompile Include="..\html\GenericCachedHTMLCollection.cpp" />
+    <ClCompile Include="..\platform\graphics\ca\win\WebTiledBackingLayerWin.cpp">
+      <Filter>platform\graphics\ca\win</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\Modules\geolocation\Coordinates.h">
     <ClInclude Include="..\dom\ChildNodeList.h">
       <Filter>dom</Filter>
     </ClInclude>
-    <ClInclude Include="..\dom\ClassNodeList.h">
-      <Filter>dom</Filter>
-    </ClInclude>
     <ClInclude Include="..\dom\ClientRect.h">
       <Filter>dom</Filter>
     </ClInclude>
     <ClInclude Include="..\page\DOMSecurityPolicy.h">
       <Filter>page</Filter>
     </ClInclude>
+    <ClInclude Include="..\ForwardingHeaders\inspector\InspectorFrontendRouter.h" />
+    <ClInclude Include="..\platform\network\DataURLDecoder.h" />
+    <ClInclude Include="..\dom\ClassCollection.h" />
+    <ClInclude Include="..\platform\graphics\ca\win\WebTiledBackingLayerWin.h">
+      <Filter>platform\graphics\ca\win</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\css\CSSGrammar.y.in">
       <Filter>platform\win</Filter>
     </MASM>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
index d4ecc31..aa1d6cc 100644 (file)
@@ -62,9 +62,11 @@ void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer
     snprintf(text, sizeof(text), "%d", repaintCount);
     
     CGRect indicatorBox = platformCALayer->bounds();
+
+    CGContextSaveGState(context);
+
     indicatorBox.size.width = 12 + 10 * strlen(text);
     indicatorBox.size.height = 27;
-    CGContextSaveGState(context);
     
     CGContextSetAlpha(context, 0.5f);
     CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0);
@@ -81,15 +83,27 @@ void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer
     else
         CGContextSetRGBFillColor(context, 1, 1, 1, 1);
     
+    platformCALayer->drawTextAtPoint(context, indicatorBox.origin.x + 5, indicatorBox.origin.y + 22, text, strlen(text));
+    
+    CGContextEndTransparencyLayer(context);
+    CGContextRestoreGState(context);
+}
+
+void PlatformCALayer::flipContext(CGContextRef context, CGFloat height)
+{
+    CGContextScaleCTM(context, 1, -1);
+    CGContextTranslateCTM(context, 0, -height);
+}
+
+// This function is needed to work around a bug in Windows CG <rdar://problem/22703470>
+void PlatformCALayer::drawTextAtPoint(CGContextRef context, CGFloat x, CGFloat y, const char* text, size_t length) const
+{
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
     CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1, -1));
     CGContextSelectFont(context, "Helvetica", 22, kCGEncodingMacRoman);
-    CGContextShowTextAtPoint(context, indicatorBox.origin.x + 5, indicatorBox.origin.y + 22, text, strlen(text));
+    CGContextShowTextAtPoint(context, x, y, text, length);
 #pragma clang diagnostic pop
-    
-    CGContextEndTransparencyLayer(context);
-    CGContextRestoreGState(context);
 }
 
 PassRefPtr<PlatformCALayer> PlatformCALayer::createCompatibleLayerOrTakeFromPool(PlatformCALayer::LayerType layerType, PlatformCALayerClient* client, IntSize size)
index 84976e6..23ed6a8 100644 (file)
@@ -226,6 +226,10 @@ public:
 
     virtual TiledBacking* tiledBacking() = 0;
 
+    virtual void drawTextAtPoint(CGContextRef, CGFloat x, CGFloat y, const char* text, size_t length) const;
+
+    static void flipContext(CGContextRef, CGFloat height);
+
 #if PLATFORM(WIN)
     virtual PlatformCALayer* rootLayer() const = 0;
     virtual void setNeedsLayout() = 0;
index 567b1a5..74b9027 100644 (file)
@@ -673,8 +673,13 @@ void TileGrid::platformCALayerPaintContents(PlatformCALayer* platformCALayer, Gr
     }
 
     int repaintCount = platformCALayerIncrementRepaintCount(platformCALayer);
-    if (m_controller.rootLayer().owner()->platformCALayerShowRepaintCounter(0))
+    if (m_controller.rootLayer().owner()->platformCALayerShowRepaintCounter(0)) {
+#if OS(WINDOWS)
+        // Tiled layers in Windows have flipped coordinates
+        PlatformCALayer::flipContext(context.platformContext(), platformCALayer->bounds().size().height());
+#endif
         PlatformCALayer::drawRepaintIndicator(context.platformContext(), platformCALayer, repaintCount, cachedCGColor(m_controller.tileDebugBorderColor(), ColorSpaceDeviceRGB));
+    }
 
     if (m_controller.scrollingPerformanceLoggingEnabled()) {
         FloatRect visiblePart(platformCALayer->position().x(), platformCALayer->position().y(), platformCALayer->bounds().size().width(), platformCALayer->bounds().size().height());
index 45692cf..446d06b 100644 (file)
 #include "GraphicsContext.h"
 #include "PlatformCAAnimationWin.h"
 #include "PlatformCALayerWinInternal.h"
+#include "TextRun.h"
 #include "TileController.h"
 #include "WebCoreHeaderDetection.h"
+#include "WebTiledBackingLayerWin.h"
 #include <QuartzCore/CoreAnimationCF.h>
 #include <WebKitSystemInterface/WebKitSystemInterface.h>
 #include <wtf/CurrentTime.h>
@@ -142,17 +144,20 @@ PlatformCALayerWin::PlatformCALayerWin(LayerType layerType, PlatformLayer* layer
 #endif
 
     // Create the PlatformCALayerWinInternal object and point to it in the userdata.
-    PlatformCALayerWinInternal* intern = new PlatformCALayerWinInternal(this);
+    PlatformCALayerWinInternal* intern = nullptr;
+
+    if (usesTiledBackingLayer()) {
+        intern = new WebTiledBackingLayerWin(this);
+        TileController* tileController = reinterpret_cast<WebTiledBackingLayerWin*>(intern)->createTileController(this);
+        m_customSublayers = std::make_unique<PlatformCALayerList>(tileController->containerLayers());
+    } else
+        intern = new PlatformCALayerWinInternal(this);
+
     CACFLayerSetUserData(m_layer.get(), intern);
 
     // Set the display callback
     CACFLayerSetDisplayCallback(m_layer.get(), displayCallback);
     CACFLayerSetLayoutCallback(m_layer.get(), layoutSublayersProc);
-
-    if (usesTiledBackingLayer()) {
-        TileController* tileController = intern->createTileController(this);
-        m_customSublayers = std::make_unique<PlatformCALayerList>(tileController->containerLayers());
-    }
 }
 
 PlatformCALayerWin::~PlatformCALayerWin()
@@ -160,9 +165,12 @@ PlatformCALayerWin::~PlatformCALayerWin()
     // Toss all the kids
     removeAllSublayers();
 
-    // Get rid of the user data
     PlatformCALayerWinInternal* layerIntern = intern(this);
-    CACFLayerSetUserData(m_layer.get(), 0);
+    if (usesTiledBackingLayer())
+        reinterpret_cast<WebTiledBackingLayerWin*>(layerIntern)->invalidate();
+
+    // Get rid of the user data
+    CACFLayerSetUserData(m_layer.get(), nullptr);
 
     CACFLayerRemoveFromSuperlayer(m_layer.get());
 
@@ -358,12 +366,12 @@ void PlatformCALayerWin::setMask(PlatformCALayer* layer)
 
 bool PlatformCALayerWin::isOpaque() const
 {
-    return CACFLayerIsOpaque(m_layer.get());
+    return intern(this)->isOpaque();
 }
 
 void PlatformCALayerWin::setOpaque(bool value)
 {
-    CACFLayerSetOpaque(m_layer.get(), value);
+    intern(this)->setOpaque(value);
     setNeedsCommit();
 }
 
@@ -526,19 +534,13 @@ void PlatformCALayerWin::setBackgroundColor(const Color& value)
 
 void PlatformCALayerWin::setBorderWidth(float value)
 {
-    CACFLayerSetBorderWidth(m_layer.get(), value);
+    intern(this)->setBorderWidth(value);
     setNeedsCommit();
 }
 
 void PlatformCALayerWin::setBorderColor(const Color& value)
 {
-    CGFloat components[4];
-    value.getRGBA(components[0], components[1], components[2], components[3]);
-
-    RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
-    RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components));
-
-    CACFLayerSetBorderColor(m_layer.get(), color.get());
+    intern(this)->setBorderColor(value);
     setNeedsCommit();
 }
 
@@ -587,18 +589,13 @@ void PlatformCALayerWin::setEdgeAntialiasingMask(unsigned mask)
 
 float PlatformCALayerWin::contentsScale() const
 {
-#if HAVE(CACFLAYER_SETCONTENTSSCALE)
-    return CACFLayerGetContentsScale(m_layer.get());
-#else
-    return 1.0f;
-#endif
+    return intern(this)->contentsScale();
 }
 
 void PlatformCALayerWin::setContentsScale(float scaleFactor)
 {
-#if HAVE(CACFLAYER_SETCONTENTSSCALE)
-    CACFLayerSetContentsScale(m_layer.get(), scaleFactor);
-#endif
+    intern(this)->setContentsScale(scaleFactor);
+    setNeedsCommit();
 }
 
 float PlatformCALayerWin::cornerRadius() const
@@ -776,5 +773,26 @@ TiledBacking* PlatformCALayerWin::tiledBacking()
     if (!usesTiledBackingLayer())
         return nullptr;
 
-    return intern(this)->tiledBacking();
+    return reinterpret_cast<WebTiledBackingLayerWin*>(intern(this))->tiledBacking();
+}
+
+void PlatformCALayerWin::drawTextAtPoint(CGContextRef context, CGFloat x, CGFloat y, const char* message, size_t length) const
+{
+    String text(message, length);
+
+    FontDescription desc;
+
+    NONCLIENTMETRICS metrics;
+    metrics.cbSize = sizeof(metrics);
+    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
+    desc.setOneFamily(metrics.lfSmCaptionFont.lfFaceName);
+
+    desc.setComputedSize(18);
+
+    FontCascade font = FontCascade(desc, 0, 0);
+    font.update(nullptr);
+
+    GraphicsContext cg(context);
+    cg.setFillColor(Color::black, ColorSpaceDeviceRGB);
+    cg.drawText(font, TextRun(text), IntPoint(x, y));
 }
index c1e942b..0c8f6b7 100644 (file)
@@ -148,6 +148,7 @@ public:
     virtual PlatformCALayer* rootLayer() const override;
     virtual void setNeedsLayout() override;
     virtual void setNeedsCommit() override;
+    virtual void drawTextAtPoint(CGContextRef, CGFloat x, CGFloat y, const char* text, size_t length) const override;
 
 #ifndef NDEBUG
     virtual void printTree() const override;
index 5761392..4aeb32a 100644 (file)
@@ -30,7 +30,6 @@
 #include "FontCascade.h"
 #include "GraphicsContext.h"
 #include "PlatformCALayer.h"
-#include "TextRun.h"
 #include "TileController.h"
 #include "TiledBacking.h"
 #include "WebCoreHeaderDetection.h"
 using namespace std;
 using namespace WebCore;
 
-// The width and height of a single tile in a tiled layer. Should be large enough to
-// avoid lots of small tiles (and therefore lots of drawing callbacks), but small enough
-// to keep the overall tile cost low.
-static const int cTiledLayerTileSize = 512;
-
-static bool layerTypeIsTiled(const PlatformCALayer::LayerType layerType)
-{
-    return layerType == PlatformCALayer::LayerTypeWebTiledLayer
-        || layerType == PlatformCALayer::LayerTypePageTiledBackingLayer
-        || layerType == PlatformCALayer::LayerTypeTiledBackingLayer;
-}
-
 PlatformCALayerWinInternal::PlatformCALayerWinInternal(PlatformCALayer* owner)
-    : m_tileSize(CGSizeMake(cTiledLayerTileSize, cTiledLayerTileSize))
-    , m_constrainedSize(constrainedSize(owner->bounds().size()))
-    , m_owner(owner)
+    : m_owner(owner)
 {
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        // Tiled layers are placed in a child layer that is always the first child of the TiledLayer
-        m_tileParent = adoptCF(CACFLayerCreate(kCACFLayer));
-        CACFLayerInsertSublayer(m_owner->platformLayer(), m_tileParent.get(), 0);
-#if HAVE(CACFLAYER_SETCONTENTSSCALE)
-        CACFLayerSetContentsScale(m_tileParent.get(), CACFLayerGetContentsScale(m_owner->platformLayer()));
-#endif
-
-        updateTiles();
-    }
 }
 
 PlatformCALayerWinInternal::~PlatformCALayerWinInternal()
@@ -96,6 +71,17 @@ static void redispatchOnMainQueue(void* context)
     self->displayCallback(retainedContext->layer.get(), retainedContext->context.get());
 }
 
+static bool shouldInvertBeforeDrawingContent(PlatformCALayer::LayerType layerType, GraphicsLayer::CompositingCoordinatesOrientation coordinateOrientation)
+{
+    return (layerType != PlatformCALayer::LayerTypeTiledBackingTileLayer)
+        && (coordinateOrientation == GraphicsLayer::CompositingCoordinatesTopDown);
+}
+
+static bool repaintCountersAreDrawnByGridController(PlatformCALayer::LayerType layerType)
+{
+    return layerType == PlatformCALayer::LayerTypeTiledBackingTileLayer;
+}
+
 void PlatformCALayerWinInternal::displayCallback(CACFLayerRef caLayer, CGContextRef context)
 {
     if (!isMainThread()) {
@@ -109,74 +95,45 @@ void PlatformCALayerWinInternal::displayCallback(CACFLayerRef caLayer, CGContext
     CGContextSaveGState(context);
 
     CGRect layerBounds = owner()->bounds();
-    if (owner()->owner()->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesTopDown) {
-        CGContextScaleCTM(context, 1, -1);
-        CGContextTranslateCTM(context, 0, -layerBounds.size.height);
-    }
+    PlatformCALayer::LayerType layerType = owner()->layerType();
 
-    if (owner()->owner()) {
-        GraphicsContext graphicsContext(context);
+    PlatformCALayerClient* client = owner()->owner();
+    GraphicsLayer::CompositingCoordinatesOrientation orientation = client->platformCALayerContentsOrientation();
 
-        // It's important to get the clip from the context, because it may be significantly
-        // smaller than the layer bounds (e.g. tiled layers)
-        CGRect clipBounds = CGContextGetClipBoundingBox(context);
-        IntRect clip(enclosingIntRect(clipBounds));
-        owner()->owner()->platformCALayerPaintContents(owner(), graphicsContext, clip);
-    }
-#ifndef NDEBUG
-    else {
-        ASSERT_NOT_REACHED();
-
-        // FIXME: ideally we'd avoid calling -setNeedsDisplay on a layer that is a plain color,
-        // so CA never makes backing store for it (which is what -setNeedsDisplay will do above).
-        CGContextSetRGBFillColor(context, 0.0f, 1.0f, 0.0f, 1.0f);
-        CGContextFillRect(context, layerBounds);
-    }
-#endif
+    if (shouldInvertBeforeDrawingContent(layerType, orientation))
+        PlatformCALayer::flipContext(context, layerBounds.size.height);
+
+    GraphicsContext graphicsContext(context);
 
-    if (owner()->owner()->platformCALayerShowRepaintCounter(owner())) {
-        String text = String::number(owner()->owner()->platformCALayerIncrementRepaintCount(owner()));
-
-        CGContextSaveGState(context);
-
-        // Make the background of the counter the same as the border color,
-        // unless there is no border, then make it red
-        float borderWidth = CACFLayerGetBorderWidth(caLayer);
-        if (borderWidth > 0) {
-            CGColorRef borderColor = CACFLayerGetBorderColor(caLayer);
-            const CGFloat* colors = CGColorGetComponents(borderColor);
-            CGContextSetRGBFillColor(context, colors[0], colors[1], colors[2], colors[3]);
-        } else
-            CGContextSetRGBFillColor(context, 1.0f, 0.0f, 0.0f, 0.8f);
-        
-        CGRect aBounds = layerBounds;
-
-        aBounds.size.width = 10 + 10 * text.length();
-        aBounds.size.height = 22;
-        CGContextFillRect(context, aBounds);
-        
-        FontDescription desc;
-
-        NONCLIENTMETRICS metrics;
-        metrics.cbSize = sizeof(metrics);
-        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
-        desc.setOneFamily(metrics.lfSmCaptionFont.lfFaceName);
-
-        desc.setComputedSize(18);
-        
-        FontCascade font = FontCascade(desc, 0, 0);
-        font.update(0);
-
-        GraphicsContext cg(context);
-        cg.setFillColor(Color::black, ColorSpaceDeviceRGB);
-        cg.drawText(font, TextRun(text), IntPoint(aBounds.origin.x + 5, aBounds.origin.y + 17));
-
-        CGContextRestoreGState(context);        
+    // It's important to get the clip from the context, because it may be significantly
+    // smaller than the layer bounds (e.g. tiled layers)
+    CGRect clipBounds = CGContextGetClipBoundingBox(context);
+    IntRect clip(enclosingIntRect(clipBounds));
+    client->platformCALayerPaintContents(owner(), graphicsContext, clip);
+
+    if (client->platformCALayerShowRepaintCounter(owner())
+        && !repaintCountersAreDrawnByGridController(layerType)) {
+        int drawCount = client->platformCALayerIncrementRepaintCount(owner());
+        drawRepaintCounters(caLayer, context, layerBounds, drawCount);
     }
 
     CGContextRestoreGState(context);
 
-    owner()->owner()->platformCALayerLayerDidDisplay(owner());
+    client->platformCALayerLayerDidDisplay(owner());
+}
+
+void PlatformCALayerWinInternal::drawRepaintCounters(CACFLayerRef caLayer, CGContextRef context, CGRect layerBounds, int drawCount)
+{
+    CGColorRef backgroundColor = nullptr;
+    // Make the background of the counter the same as the border color,
+    // unless there is no border, then make it red
+    float borderWidth = CACFLayerGetBorderWidth(caLayer);
+    if (borderWidth > 0)
+        backgroundColor = CACFLayerGetBorderColor(caLayer);
+    else
+        backgroundColor = cachedCGColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
+
+    PlatformCALayer::drawRepaintIndicator(context, owner(), drawCount, backgroundColor);
 }
 
 void PlatformCALayerWinInternal::internalSetNeedsDisplay(const FloatRect* dirtyRect)
@@ -185,51 +142,43 @@ void PlatformCALayerWinInternal::internalSetNeedsDisplay(const FloatRect* dirtyR
         CGRect rect = *dirtyRect;
         CACFLayerSetNeedsDisplay(owner()->platformLayer(), &rect);
     } else
-        CACFLayerSetNeedsDisplay(owner()->platformLayer(), 0);
+        CACFLayerSetNeedsDisplay(owner()->platformLayer(), nullptr);
 }
 
 void PlatformCALayerWinInternal::setNeedsDisplay()
 {
-    internalSetNeedsDisplay(0);
+    internalSetNeedsDisplay(nullptr);
 }
 
 void PlatformCALayerWinInternal::setNeedsDisplayInRect(const FloatRect& dirtyRect)
 {
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        // FIXME: Only setNeedsDisplay for tiles that are currently visible
-        int numTileLayers = tileCount();
-        CGRect rect = dirtyRect;
-        for (int i = 0; i < numTileLayers; ++i)
-            CACFLayerSetNeedsDisplay(tileAtIndex(i), &rect);
-
-        if (m_owner->owner() && m_owner->owner()->platformCALayerShowRepaintCounter(m_owner)) {
-            CGRect layerBounds = m_owner->bounds();
-            CGRect indicatorRect = CGRectMake(layerBounds.origin.x, layerBounds.origin.y, 80, 25);
-            CACFLayerSetNeedsDisplay(tileAtIndex(0), &indicatorRect);
+    if (!owner())
+        return;
+
+    ASSERT(owner()->layerType() != PlatformCALayer::LayerTypeTiledBackingLayer);
+
+    if (owner()->owner()) {
+        if (owner()->owner()->platformCALayerShowRepaintCounter(owner())) {
+            FloatRect layerBounds = owner()->bounds();
+            FloatRect repaintCounterRect = layerBounds;
+
+            // We assume a maximum of 4 digits and a font size of 18.
+            repaintCounterRect.setWidth(80);
+            repaintCounterRect.setHeight(22);
+            if (owner()->owner()->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesTopDown)
+                repaintCounterRect.setY(layerBounds.height() - (layerBounds.y() + repaintCounterRect.height()));
+            internalSetNeedsDisplay(&repaintCounterRect);
         }
-    } else if (owner()->layerType() == PlatformCALayer::LayerTypeWebLayer) {
-        if (owner() && owner()->owner()) {
-            if (owner()->owner()->platformCALayerShowRepaintCounter(owner())) {
-                FloatRect layerBounds = owner()->bounds();
-                FloatRect repaintCounterRect = layerBounds;
-
-                // We assume a maximum of 4 digits and a font size of 18.
-                repaintCounterRect.setWidth(80);
-                repaintCounterRect.setHeight(22);
-                if (owner()->owner()->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesTopDown)
-                    repaintCounterRect.setY(layerBounds.height() - (layerBounds.y() + repaintCounterRect.height()));
-                internalSetNeedsDisplay(&repaintCounterRect);
-            }
-            if (owner()->owner()->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesTopDown) {
-                FloatRect flippedDirtyRect = dirtyRect;
-                flippedDirtyRect.setY(owner()->bounds().height() - (flippedDirtyRect.y() + flippedDirtyRect.height()));
-                internalSetNeedsDisplay(&flippedDirtyRect);
-                return;
-            }
+        if (owner()->owner()->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesTopDown) {
+            FloatRect flippedDirtyRect = dirtyRect;
+            flippedDirtyRect.setY(owner()->bounds().height() - (flippedDirtyRect.y() + flippedDirtyRect.height()));
+            internalSetNeedsDisplay(&flippedDirtyRect);
+            return;
         }
-
-        internalSetNeedsDisplay(&dirtyRect);
     }
+
+    internalSetNeedsDisplay(&dirtyRect);
+
     owner()->setNeedsCommit();
 }
 
@@ -247,11 +196,6 @@ void PlatformCALayerWinInternal::setSublayers(const PlatformCALayerList& list)
         CACFLayerInsertSublayer(owner()->platformLayer(), list[i]->platformLayer(), i);
 
     owner()->setNeedsCommit();
-
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        // Preserve the tile parent after set
-        CACFLayerInsertSublayer(owner()->platformLayer(), m_tileParent.get(), 0);
-    }
 }
 
 void PlatformCALayerWinInternal::getSublayers(PlatformCALayerList& list) const
@@ -264,35 +208,20 @@ void PlatformCALayerWinInternal::getSublayers(PlatformCALayerList& list) const
 
     size_t count = CFArrayGetCount(sublayers);
 
-    size_t layersToSkip = 0;
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        // Exclude the tile parent layer.
-        layersToSkip = 1;
-    }
-
-    list.resize(count - layersToSkip);
-    for (size_t arrayIndex = layersToSkip; arrayIndex < count; ++arrayIndex)
-        list[arrayIndex - layersToSkip] = PlatformCALayer::platformCALayer(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, arrayIndex)));
+    list.resize(count);
+    for (size_t arrayIndex = 0; arrayIndex < count; ++arrayIndex)
+        list[arrayIndex] = PlatformCALayer::platformCALayer(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, arrayIndex)));
 }
 
 void PlatformCALayerWinInternal::removeAllSublayers()
 {
-    CACFLayerSetSublayers(owner()->platformLayer(), 0);
+    CACFLayerSetSublayers(owner()->platformLayer(), nullptr);
     owner()->setNeedsCommit();
-
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        // Restore the tile parent after removal
-        CACFLayerInsertSublayer(owner()->platformLayer(), m_tileParent.get(), 0);
-    }
 }
 
 void PlatformCALayerWinInternal::insertSublayer(PlatformCALayer& layer, size_t index)
 {
     index = min(index, sublayerCount());
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        // Add 1 to account for the tile parent layer
-        ++index;
-    }
 
     layer.removeFromSuperlayer();
     CACFLayerInsertSublayer(owner()->platformLayer(), layer.platformLayer(), index);
@@ -302,15 +231,7 @@ void PlatformCALayerWinInternal::insertSublayer(PlatformCALayer& layer, size_t i
 size_t PlatformCALayerWinInternal::sublayerCount() const
 {
     CFArrayRef sublayers = CACFLayerGetSublayers(owner()->platformLayer());
-    size_t count = sublayers ? CFArrayGetCount(sublayers) : 0;
-
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        // Subtract 1 to account for the tile parent layer
-        ASSERT(count > 0);
-        count--;
-    }
-
-    return count;
+    return sublayers ? CFArrayGetCount(sublayers) : 0;
 }
 
 int PlatformCALayerWinInternal::indexOfSublayer(const PlatformCALayer* reference)
@@ -325,16 +246,9 @@ int PlatformCALayerWinInternal::indexOfSublayer(const PlatformCALayer* reference
 
     size_t n = CFArrayGetCount(sublayers);
 
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        for (size_t i = 1; i < n; ++i) {
-            if (CFArrayGetValueAtIndex(sublayers, i) == ref)
-                return i - 1;
-        }
-    } else {
-        for (size_t i = 0; i < n; ++i) {
-            if (CFArrayGetValueAtIndex(sublayers, i) == ref)
-                return i;
-        }
+    for (size_t i = 0; i < n; ++i) {
+        if (CFArrayGetValueAtIndex(sublayers, i) == ref)
+            return i;
     }
 
     return -1;
@@ -342,14 +256,9 @@ int PlatformCALayerWinInternal::indexOfSublayer(const PlatformCALayer* reference
 
 PlatformCALayer* PlatformCALayerWinInternal::sublayerAtIndex(int index) const
 {
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        // Add 1 to account for the tile parent layer
-        index++;
-    }
-
     CFArrayRef sublayers = CACFLayerGetSublayers(owner()->platformLayer());
     if (!sublayers || index < 0 || CFArrayGetCount(sublayers) <= index)
-        return 0;
+        return nullptr;
     
     return PlatformCALayer::platformCALayer(static_cast<CACFLayerRef>(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, index))));
 }
@@ -361,11 +270,6 @@ void PlatformCALayerWinInternal::setBounds(const FloatRect& rect)
 
     CACFLayerSetBounds(owner()->platformLayer(), rect);
     owner()->setNeedsCommit();
-
-    if (layerTypeIsTiled(m_owner->layerType())) {
-        m_constrainedSize = constrainedSize(rect.size());
-        updateTiles();
-    }
 }
 
 void PlatformCALayerWinInternal::setFrame(const FloatRect& rect)
@@ -376,166 +280,48 @@ void PlatformCALayerWinInternal::setFrame(const FloatRect& rect)
 
     CACFLayerSetFrame(owner()->platformLayer(), rect);
     owner()->setNeedsCommit();
-
-    if (layerTypeIsTiled(m_owner->layerType()))
-        updateTiles();
 }
 
-CGSize PlatformCALayerWinInternal::constrainedSize(const CGSize& size) const
+bool PlatformCALayerWinInternal::isOpaque() const
 {
-    const int cMaxTileCount = 512;
-    const float cSqrtMaxTileCount = sqrtf(cMaxTileCount);
-
-    CGSize constrainedSize = size;
-
-    int tileColumns = ceilf(constrainedSize.width / m_tileSize.width);
-    int tileRows = ceilf(constrainedSize.height / m_tileSize.height);
-
-    bool tooManyTiles = tileColumns && numeric_limits<int>::max() / tileColumns < tileRows || tileColumns * tileRows > cMaxTileCount;
-
-    // If number of tiles vertically or horizontally is < sqrt(cMaxTileCount)
-    // just shorten the longer dimension. Otherwise shorten both dimensions
-    // according to the ratio of width to height
-
-    if (tooManyTiles) {
-        if (tileRows < cSqrtMaxTileCount)
-            tileColumns = floorf(cMaxTileCount / tileRows);
-        else if (tileColumns < cSqrtMaxTileCount)
-            tileRows = floorf(cMaxTileCount / tileColumns);
-        else {
-            tileRows = ceilf(sqrtf(cMaxTileCount * constrainedSize.height / constrainedSize.width));
-            tileColumns = floorf(cMaxTileCount / tileRows);
-        }
-        
-        constrainedSize.width = tileColumns * m_tileSize.width;
-        constrainedSize.height = tileRows * m_tileSize.height;
-    }
-    
-    return constrainedSize;
+    return CACFLayerIsOpaque(owner()->platformLayer());
 }
 
-void PlatformCALayerWinInternal::tileDisplayCallback(CACFLayerRef layer, CGContextRef context)
+void PlatformCALayerWinInternal::setOpaque(bool value)
 {
-    static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(layer))->drawTile(layer, context);
+    CACFLayerSetOpaque(owner()->platformLayer(), value);
 }
 
-void PlatformCALayerWinInternal::addTile()
+float PlatformCALayerWinInternal::contentsScale() const
 {
-    RetainPtr<CACFLayerRef> newLayer = adoptCF(CACFLayerCreate(kCACFLayer));
-    CACFLayerSetAnchorPoint(newLayer.get(), CGPointMake(0, 1));
-    CACFLayerSetUserData(newLayer.get(), this);
-    CACFLayerSetDisplayCallback(newLayer.get(), tileDisplayCallback);
 #if HAVE(CACFLAYER_SETCONTENTSSCALE)
-    CACFLayerSetContentsScale(newLayer.get(), CACFLayerGetContentsScale(m_tileParent.get()));
+    return CACFLayerGetContentsScale(owner()->platformLayer());
+#else
+    return 1.0f;
 #endif
-
-    CFArrayRef sublayers = CACFLayerGetSublayers(m_tileParent.get());
-    CACFLayerInsertSublayer(m_tileParent.get(), newLayer.get(), sublayers ? CFArrayGetCount(sublayers) : 0);
-
-    if (owner()->owner()->platformCALayerShowDebugBorders()) {
-        CGColorRef borderColor = CGColorCreateGenericRGB(0.5, 0, 0.5, 0.7);
-        CACFLayerSetBorderColor(newLayer.get(), borderColor);
-        CGColorRelease(borderColor);
-        CACFLayerSetBorderWidth(newLayer.get(), 2);
-    }
 }
 
-void PlatformCALayerWinInternal::removeTile()
+void PlatformCALayerWinInternal::setContentsScale(float scaleFactor)
 {
-    CACFLayerRemoveFromSuperlayer(tileAtIndex(tileCount() - 1));
-}
-
-CACFLayerRef PlatformCALayerWinInternal::tileAtIndex(int index)
-{
-    CFArrayRef sublayers = CACFLayerGetSublayers(m_tileParent.get());
-    if (!sublayers || index < 0 || index >= tileCount())
-        return 0;
-    
-    return static_cast<CACFLayerRef>(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, index)));
-}
-
-int PlatformCALayerWinInternal::tileCount() const
-{
-    CFArrayRef sublayers = CACFLayerGetSublayers(m_tileParent.get());
-    return sublayers ? CFArrayGetCount(sublayers) : 0;
+#if HAVE(CACFLAYER_SETCONTENTSSCALE)
+    CACFLayerSetContentsScale(owner()->platformLayer(), scaleFactor);
+#endif
 }
 
-void PlatformCALayerWinInternal::updateTiles()
+void PlatformCALayerWinInternal::setBorderWidth(float value)
 {
-    // FIXME: In addition to redoing the number of tiles, we need to only render and have backing
-    // store for visible layers
-    int numTilesHorizontal = ceil(m_constrainedSize.width / m_tileSize.width);
-    int numTilesVertical = ceil(m_constrainedSize.height / m_tileSize.height);
-    int numTilesTotal = numTilesHorizontal * numTilesVertical;
-    ASSERT(!m_constrainedSize.height || !m_constrainedSize.width || numTilesTotal > 0);
-
-    int numTilesToChange = numTilesTotal - tileCount();
-    if (numTilesToChange >= 0) {
-        // Add new tiles
-        for (int i = 0; i < numTilesToChange; ++i)
-            addTile();
-    } else {
-        // Remove old tiles
-        numTilesToChange = -numTilesToChange;
-        for (int i = 0; i < numTilesToChange; ++i)
-            removeTile();
-    }
-
-    // Set coordinates for all tiles
-    CFArrayRef tileArray = CACFLayerGetSublayers(m_tileParent.get());
-
-    for (int i = 0; i < numTilesHorizontal; ++i) {
-        for (int j = 0; j < numTilesVertical; ++j) {
-            CACFLayerRef tile = static_cast<CACFLayerRef>(const_cast<void*>(CFArrayGetValueAtIndex(tileArray, i * numTilesVertical + j)));
-            CACFLayerSetPosition(tile, CGPointMake(i * m_tileSize.width, j * m_tileSize.height));
-            int width = min(m_tileSize.width, m_constrainedSize.width - i * m_tileSize.width);
-            int height = min(m_tileSize.height, m_constrainedSize.height - j * m_tileSize.height);
-            CACFLayerSetBounds(tile, CGRectMake(i * m_tileSize.width, j * m_tileSize.height, width, height));
-
-            // Flip Y to compensate for the flipping that happens during render to match the CG context coordinate space
-            CATransform3D transform = CATransform3DMakeScale(1, -1, 1);
-            CATransform3DTranslate(transform, 0, height, 0);
-            CACFLayerSetTransform(tile, transform);
-
-#ifndef NDEBUG
-            String name = "Tile (" + String::number(i) + "," + String::number(j) + ")";
-            CACFLayerSetName(tile, name.createCFString().get());
-#endif
-        }
-    }
+    CACFLayerSetBorderWidth(owner()->platformLayer(), value);
 }
 
-void PlatformCALayerWinInternal::drawTile(CACFLayerRef tile, CGContextRef context)
+void PlatformCALayerWinInternal::setBorderColor(const Color& value)
 {
-    CGPoint tilePosition = CACFLayerGetPosition(tile);
-    CGRect tileBounds = CACFLayerGetBounds(tile);
+    CGFloat components[4] = { 0, 0, 0, 0 };
+    RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB());
 
-    CGContextSaveGState(context);
+    if (value.isValid())
+        value.getRGBA(components[0], components[1], components[2], components[3]);
 
-    // Set the context clipping rectangle to the current tile
-    CGContextClipToRect(context, CGRectMake(tilePosition.x, tilePosition.y, tileBounds.size.width, tileBounds.size.height));
+    RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components));
 
-    if (owner()->owner()->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesTopDown) {
-        // If the layer is rendering top-down, it will flip the coordinates in y. Tiled layers are
-        // already flipping, so we need to undo that here.
-        CGContextTranslateCTM(context, 0, owner()->bounds().height());
-        CGContextScaleCTM(context, 1, -1);
-    }
-
-    // Draw the tile
-    displayCallback(owner()->platformLayer(), context);
-
-    CGContextRestoreGState(context);
-}
-
-TileController* PlatformCALayerWinInternal::createTileController(PlatformCALayer* rootLayer)
-{
-    ASSERT(!m_tileController);
-    m_tileController = std::make_unique<TileController>(rootLayer);
-    return m_tileController.get();
-}
-
-TiledBacking* PlatformCALayerWinInternal::tiledBacking()
-{
-    return m_tileController.get();
+    CACFLayerSetBorderColor(owner()->platformLayer(), color.get());
 }
index 6d514ff..a562523 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,6 +35,7 @@ typedef struct CGContext *CGContextRef;
 
 namespace WebCore {
 
+class Color;
 class FloatRect;
 class PlatformCALayer;
 class TileController;
@@ -47,9 +48,9 @@ public:
     PlatformCALayerWinInternal(PlatformCALayer*);
     ~PlatformCALayerWinInternal();
 
-    void displayCallback(CACFLayerRef, CGContextRef);
-    void setNeedsDisplayInRect(const FloatRect&);
-    void setNeedsDisplay();
+    virtual void displayCallback(CACFLayerRef, CGContextRef);
+    virtual void setNeedsDisplayInRect(const FloatRect&);
+    virtual void setNeedsDisplay();
     PlatformCALayer* owner() const { return m_owner; }
 
     void setSublayers(const PlatformCALayerList&);
@@ -59,32 +60,26 @@ public:
     size_t sublayerCount() const;
     int indexOfSublayer(const PlatformCALayer* reference);
 
-    void setBounds(const FloatRect&);
+    virtual bool isOpaque() const;
+    virtual void setOpaque(bool);
+
+    virtual void setBounds(const FloatRect&);
     void setFrame(const FloatRect&);
 
-    TileController* createTileController(PlatformCALayer* rootLayer);
-    TiledBacking* tiledBacking();
+    virtual float contentsScale() const;
+    virtual void setContentsScale(float);
+
+    virtual void setBorderWidth(float);
+
+    virtual void setBorderColor(const Color&);
+
+    void drawRepaintCounters(CACFLayerRef, CGContextRef, CGRect layerBounds, int drawCount);
 
 private:
     void internalSetNeedsDisplay(const FloatRect*);
     PlatformCALayer* sublayerAtIndex(int) const;
 
-    static void tileDisplayCallback(CACFLayerRef, CGContextRef);
-
-    void drawTile(CACFLayerRef, CGContextRef);
-    CGSize constrainedSize(const CGSize&) const;
-    void addTile();
-    void removeTile();
-    CACFLayerRef tileAtIndex(int);
-    int tileCount() const;
-    void updateTiles();
-
     PlatformCALayer* m_owner;
-
-    CGSize m_tileSize;
-    CGSize m_constrainedSize;
-    RetainPtr<CACFLayerRef> m_tileParent;
-    std::unique_ptr<TileController> m_tileController;
 };
 
 }
diff --git a/Source/WebCore/platform/graphics/ca/win/WebTiledBackingLayerWin.cpp b/Source/WebCore/platform/graphics/ca/win/WebTiledBackingLayerWin.cpp
new file mode 100644 (file)
index 0000000..22370c4
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "WebTiledBackingLayerWin.h"
+
+#include "GraphicsContext.h"
+#include "PlatformCALayer.h"
+#include "TileController.h"
+#include "TiledBacking.h"
+#include <QuartzCore/CACFLayer.h>
+#include <wtf/MainThread.h>
+
+using namespace std;
+using namespace WebCore;
+
+WebTiledBackingLayerWin::WebTiledBackingLayerWin(PlatformCALayer* owner)
+    : PlatformCALayerWinInternal(owner)
+{
+}
+
+WebTiledBackingLayerWin::~WebTiledBackingLayerWin()
+{
+}
+
+struct DisplayOnMainThreadContext {
+    RetainPtr<CACFLayerRef> layer;
+    RetainPtr<CGContextRef> context;
+
+    DisplayOnMainThreadContext(CACFLayerRef caLayer, CGContextRef caContext)
+        : layer(caLayer)
+        , context(caContext)
+    {
+    }
+};
+
+static void redispatchOnMainQueue(void* context)
+{
+    ASSERT(isMainThread());
+    std::unique_ptr<DisplayOnMainThreadContext> retainedContext(reinterpret_cast<DisplayOnMainThreadContext*>(context));
+    if (!retainedContext)
+        return;
+
+    PlatformCALayerWinInternal* self = static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(retainedContext->layer.get()));
+
+    self->displayCallback(retainedContext->layer.get(), retainedContext->context.get());
+}
+
+void WebTiledBackingLayerWin::displayCallback(CACFLayerRef caLayer, CGContextRef context)
+{
+    if (!isMainThread()) {
+        dispatch_async_f(dispatch_get_main_queue(), new DisplayOnMainThreadContext(caLayer, context), redispatchOnMainQueue);
+        return;
+    }
+    
+    if (!owner() || !owner()->owner())
+        return;
+
+    CGContextSaveGState(context);
+
+    CGRect layerBounds = owner()->bounds();
+    PlatformCALayer::LayerType layerType = owner()->layerType();
+    ASSERT(layerType == PlatformCALayer::LayerTypeTiledBackingLayer);
+
+    PlatformCALayerClient* client = owner()->owner();
+    GraphicsLayer::CompositingCoordinatesOrientation orientation = client->platformCALayerContentsOrientation();
+
+    PlatformCALayer::flipContext(context, layerBounds.size.height);
+
+    GraphicsContext graphicsContext(context);
+
+    // It's important to get the clip from the context, because it may be significantly
+    // smaller than the layer bounds (e.g. tiled layers)
+    CGRect clipBounds = CGContextGetClipBoundingBox(context);
+    IntRect clip(enclosingIntRect(clipBounds));
+    client->platformCALayerPaintContents(owner(), graphicsContext, clip);
+
+    if (client->platformCALayerShowRepaintCounter(owner())) {
+        int drawCount = client->platformCALayerIncrementRepaintCount(owner());
+        drawRepaintCounters(caLayer, context, layerBounds, drawCount);
+    }
+
+    CGContextRestoreGState(context);
+
+    client->platformCALayerLayerDidDisplay(owner());
+}
+
+void WebTiledBackingLayerWin::setNeedsDisplay()
+{
+    if (m_tileController)
+        return m_tileController->setNeedsDisplay();
+}
+
+void WebTiledBackingLayerWin::setNeedsDisplayInRect(const FloatRect& dirtyRect)
+{
+    if (m_tileController)
+        return m_tileController->setNeedsDisplayInRect(enclosingIntRect(dirtyRect));
+}
+
+void WebTiledBackingLayerWin::setBounds(const FloatRect& bounds)
+{
+    if (CGRectEqualToRect(bounds, owner()->bounds()))
+        return;
+
+    PlatformCALayerWinInternal::setBounds(bounds);
+
+    if (m_tileController)
+        m_tileController->tileCacheLayerBoundsChanged();
+}
+
+bool WebTiledBackingLayerWin::isOpaque() const
+{
+    return m_tileController ? m_tileController->tilesAreOpaque() : true;
+}
+
+void WebTiledBackingLayerWin::setOpaque(bool value)
+{
+    if (m_tileController)
+        return m_tileController->setTilesOpaque(value);
+}
+
+float WebTiledBackingLayerWin::contentsScale() const
+{
+    return m_tileController ? m_tileController->contentsScale() : 1.0f;
+}
+
+void WebTiledBackingLayerWin::setContentsScale(float scaleFactor)
+{
+    if (m_tileController)
+        return m_tileController->setContentsScale(scaleFactor);
+}
+
+void WebTiledBackingLayerWin::setBorderWidth(float value)
+{
+    if (m_tileController)
+        return m_tileController->setTileDebugBorderWidth(value / 2);
+}
+
+void WebTiledBackingLayerWin::setBorderColor(const Color& value)
+{
+    if (m_tileController)
+        return m_tileController->setTileDebugBorderColor(value);
+}
+
+TileController* WebTiledBackingLayerWin::createTileController(PlatformCALayer* rootLayer)
+{
+    ASSERT(!m_tileController);
+    m_tileController = std::make_unique<TileController>(rootLayer);
+    return m_tileController.get();
+}
+
+TiledBacking* WebTiledBackingLayerWin::tiledBacking()
+{
+    return m_tileController.get();
+}
+
+void WebTiledBackingLayerWin::invalidate()
+{
+    ASSERT(isMainThread());
+    ASSERT(m_tileController);
+    m_tileController = nullptr;
+}
diff --git a/Source/WebCore/platform/graphics/ca/win/WebTiledBackingLayerWin.h b/Source/WebCore/platform/graphics/ca/win/WebTiledBackingLayerWin.h
new file mode 100644 (file)
index 0000000..1f0b5f7
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef WebTiledBackingLayerWin_h
+#define WebTiledBackingLayerWin_h
+
+#include "PlatformCALayerWinInternal.h"
+
+namespace WebCore {
+
+class WebTiledBackingLayerWin : public PlatformCALayerWinInternal {
+public:
+    WebTiledBackingLayerWin(PlatformCALayer*);
+    ~WebTiledBackingLayerWin();
+
+    void displayCallback(CACFLayerRef, CGContextRef) override;
+    void setNeedsDisplayInRect(const FloatRect&) override;
+    void setNeedsDisplay() override;
+
+    bool isOpaque() const override;
+    void setOpaque(bool) override;
+
+    void setBounds(const FloatRect&) override;
+
+    float contentsScale() const override;
+    void setContentsScale(float) override;
+
+    void setBorderWidth(float) override;
+
+    void setBorderColor(const Color&) override;
+
+    // WebTiledBackingLayer Features
+    TileController* createTileController(PlatformCALayer* rootLayer);
+    TiledBacking* tiledBacking();
+    void invalidate();
+
+private:
+    RetainPtr<CACFLayerRef> m_tileParent;
+    std::unique_ptr<TileController> m_tileController;
+};
+
+}
+
+#endif // WebTiledBackingLayerWin_h