Modified: trunk/Source/WebCore/ChangeLog (207862 => 207863)
--- trunk/Source/WebCore/ChangeLog 2016-10-26 01:28:03 UTC (rev 207862)
+++ trunk/Source/WebCore/ChangeLog 2016-10-26 01:57:44 UTC (rev 207863)
@@ -1,3 +1,35 @@
+2016-10-25 Brent Fulgham <[email protected]>
+
+ [Win][Direct2D] Use smart pointers for Direct2D Path types
+ https://bugs.webkit.org/show_bug.cgi?id=163994
+
+ Reviewed by Alex Christensen.
+
+ Tested by existing path tests.
+
+ * platform/graphics/Path.h:
+ (WebCore::Path::platformPath): Use a COMPtr for m_path.
+ * platform/graphics/win/GraphicsContextDirect2D.cpp:
+ (WebCore::GraphicsContext::systemFactory): Present better D2D debug output
+ when running a debug build.
+ (WebCore::GraphicsContext::platformInit): Initialize a D2D device from a
+ native GDI device context.
+ (WebCore::GraphicsContext::platformStrokeStyle): Added.
+ (WebCore::GraphicsContext::clipBounds): Simplify clip boundary calculations and
+ avoid doing math on infinities.
+ * platform/graphics/win/PathDirect2D.cpp:
+ (WebCore::scratchRenderTarget): Added.
+ (WebCore::Path::~Path): Switch to COMPtr implementation.
+ (WebCore::Path::ensurePlatformPath): Ditto.
+ (WebCore::Path::appendGeometry): Ditto.
+ (WebCore::Path::operator=): Ditto.
+ (WebCore::Path::initializePathState): Ditto.
+ (WebCore::Path::strokeContains): Provide an implementation.
+ (WebCore::Path::transform): Ditto.
+ (WebCore::Path::addEllipse): No need for explicit construction of the
+ D2D1::Point2F object.
+ (WebCore::Path::clear): Switch to COMPtr implementation.
+
2016-10-25 Nan Wang <[email protected]>
LayoutTest accessibility/mac/meter-gauge-value-description.html failing
Modified: trunk/Source/WebCore/platform/graphics/Path.h (207862 => 207863)
--- trunk/Source/WebCore/platform/graphics/Path.h 2016-10-26 01:28:03 UTC (rev 207862)
+++ trunk/Source/WebCore/platform/graphics/Path.h 2016-10-26 01:57:44 UTC (rev 207863)
@@ -165,7 +165,11 @@
// To keep Path() cheap, it does not allocate a PlatformPath immediately
// meaning Path::platformPath() can return null.
+#if USE(DIRECT2D)
+ PlatformPathPtr platformPath() const { return m_path.get(); }
+#else
PlatformPathPtr platformPath() const { return m_path; }
+#endif
// ensurePlatformPath() will allocate a PlatformPath if it has not yet been and will never return null.
WEBCORE_EXPORT PlatformPathPtr ensurePlatformPath();
@@ -199,10 +203,12 @@
#endif
private:
- PlatformPathPtr m_path { nullptr };
#if USE(DIRECT2D)
+ COMPtr<ID2D1GeometryGroup> m_path;
COMPtr<ID2D1PathGeometry> m_activePathGeometry;
COMPtr<ID2D1GeometrySink> m_activePath;
+#else
+ PlatformPathPtr m_path { nullptr };
#endif
};
Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp (207862 => 207863)
--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp 2016-10-26 01:28:03 UTC (rev 207862)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextDirect2D.cpp 2016-10-26 01:57:44 UTC (rev 207863)
@@ -71,7 +71,13 @@
{
static ID2D1Factory* direct2DFactory = nullptr;
if (!direct2DFactory) {
+#ifndef NDEBUG
+ D2D1_FACTORY_OPTIONS options = { };
+ options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
+ HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, options, &direct2DFactory);
+#else
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &direct2DFactory);
+#endif
RELEASE_ASSERT(SUCCEEDED(hr));
}
@@ -108,7 +114,23 @@
if (!hdc)
return;
- COMPtr<ID2D1RenderTarget> renderTarget;
+ HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
+
+ DIBPixelData pixelData(bitmap);
+
+ auto targetProperties = D2D1::RenderTargetProperties();
+ targetProperties.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE);
+
+ COMPtr<ID2D1DCRenderTarget> renderTarget;
+ HRESULT hr = systemFactory()->CreateDCRenderTarget(&targetProperties, &renderTarget);
+ if (!SUCCEEDED(hr))
+ return;
+
+ RECT clientRect = IntRect(IntPoint(), pixelData.size());
+ hr = renderTarget->BindDC(hdc, &clientRect);
+ if (!SUCCEEDED(hr))
+ return;
+
m_data = new GraphicsContextPlatformPrivate(renderTarget.get());
m_data->m_hdc = hdc;
// Make sure the context starts in sync with our state.
@@ -671,6 +693,11 @@
return m_d2dStrokeStyle.get();
}
+ID2D1StrokeStyle* GraphicsContext::platformStrokeStyle() const
+{
+ return m_data->strokeStyle();
+}
+
// This is only used to draw borders.
void GraphicsContext::drawLine(const FloatPoint& point1, const FloatPoint& point2)
{
@@ -1248,14 +1275,13 @@
return IntRect(-2048, -2048, 4096, 4096); // FIXME: display lists.
}
- D2D1_RECT_F d2dClipBounds = D2D1::InfiniteRect();
- FloatRect clipBounds(d2dClipBounds.left, d2dClipBounds.top, d2dClipBounds.right - d2dClipBounds.left, d2dClipBounds.bottom - d2dClipBounds.top);
+ D2D1_SIZE_F clipSize;
+ if (auto clipLayer = m_data->clipLayer())
+ clipSize = clipLayer->GetSize();
+ else
+ clipSize = platformContext()->GetSize();
- if (m_data->clipLayer()) {
- auto clipSize = m_data->clipLayer()->GetSize();
- clipBounds.setWidth(clipSize.width);
- clipBounds.setHeight(clipSize.height);
- }
+ FloatRect clipBounds(IntPoint(), clipSize);
return enclosingIntRect(clipBounds);
}
Modified: trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp (207862 => 207863)
--- trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp 2016-10-26 01:28:03 UTC (rev 207862)
+++ trunk/Source/WebCore/platform/graphics/win/PathDirect2D.cpp 2016-10-26 01:57:44 UTC (rev 207863)
@@ -42,6 +42,11 @@
namespace WebCore {
+static inline ID2D1RenderTarget* scratchRenderTarget()
+{
+ static COMPtr<ID2D1RenderTarget> renderTarget = adoptCOM(GraphicsContext::defaultRenderTarget());
+ return renderTarget.get();
+}
Path Path::polygonPathFromPoints(const Vector<FloatPoint>& points)
{
@@ -70,8 +75,6 @@
Path::~Path()
{
- if (m_path)
- m_path->Release();
}
PlatformPathPtr Path::ensurePlatformPath()
@@ -83,7 +86,7 @@
return nullptr;
}
- return m_path;
+ return m_path.get();
}
void Path::appendGeometry(ID2D1Geometry* geometry)
@@ -101,7 +104,7 @@
auto fillMode = m_path ? m_path->GetFillMode() : D2D1_FILL_MODE_WINDING;
- COMPtr<ID2D1GeometryGroup> protectedPath = adoptCOM(m_path);
+ COMPtr<ID2D1GeometryGroup> protectedPath = m_path;
m_path = nullptr;
HRESULT hr = GraphicsContext::systemFactory()->CreateGeometryGroup(fillMode, geometries.data(), geometries.size(), &m_path);
@@ -162,13 +165,7 @@
Path& Path::operator=(const Path& other)
{
- if (m_path)
- m_path->Release();
-
m_path = other.m_path;
- if (m_path)
- m_path->AddRef();
-
m_activePath = other.m_activePath;
m_activePathGeometry = other.m_activePathGeometry;
@@ -177,8 +174,6 @@
HRESULT Path::initializePathState()
{
- if (m_path)
- m_path->Release();
m_path = nullptr;
m_activePath = nullptr;
m_activePathGeometry = nullptr;
@@ -231,10 +226,17 @@
if (isNull())
return false;
- UNUSED_PARAM(applier);
- UNUSED_PARAM(point);
- notImplemented();
- return false;
+ ASSERT(applier);
+
+ GraphicsContext scratchContext(scratchRenderTarget());
+ applier->strokeStyle(&scratchContext);
+
+ BOOL containsPoint = false;
+ HRESULT hr = m_path->StrokeContainsPoint(point, scratchContext.strokeThickness(), scratchContext.platformStrokeStyle(), nullptr, 1.0f, &containsPoint);
+ if (!SUCCEEDED(hr))
+ return false;
+
+ return containsPoint;
}
void Path::translate(const FloatSize& size)
@@ -257,7 +259,7 @@
const D2D1_MATRIX_3X2_F& d2dTransform = static_cast<const D2D1_MATRIX_3X2_F>(transform);
COMPtr<ID2D1TransformedGeometry> transformedPath;
- if (!SUCCEEDED(GraphicsContext::systemFactory()->CreateTransformedGeometry(m_path, d2dTransform, &transformedPath)))
+ if (!SUCCEEDED(GraphicsContext::systemFactory()->CreateTransformedGeometry(m_path.get(), d2dTransform, &transformedPath)))
return;
Vector<ID2D1Geometry*> geometries;
@@ -271,7 +273,6 @@
auto fillMode = m_path->GetFillMode();
- m_path->Release();
m_path = nullptr;
HRESULT hr = GraphicsContext::systemFactory()->CreateGeometryGroup(fillMode, geometries.data(), geometries.size(), &m_path);
@@ -476,7 +477,7 @@
void Path::addEllipse(const FloatRect& r)
{
COMPtr<ID2D1EllipseGeometry> ellipse;
- HRESULT hr = GraphicsContext::systemFactory()->CreateEllipseGeometry(D2D1::Ellipse(D2D1::Point2F(r.center().x(), r.center().y()), r.width(), r.height()), &ellipse);
+ HRESULT hr = GraphicsContext::systemFactory()->CreateEllipseGeometry(D2D1::Ellipse(r.center(), r.width(), r.height()), &ellipse);
RELEASE_ASSERT(SUCCEEDED(hr));
appendGeometry(ellipse.get());
}
@@ -498,9 +499,6 @@
if (isNull())
return;
- if (m_path)
- m_path->Release();
-
m_path = nullptr;
m_activePath = nullptr;
m_activePathGeometry = nullptr;