Fix reference count in D2D renderer gradient brushes.

See https://github.com/wxWidgets/wxWidgets/pull/1724
This commit is contained in:
Vadim Zeitlin
2020-02-04 02:16:19 +01:00
3 changed files with 43 additions and 47 deletions

View File

@@ -371,11 +371,11 @@ public:
wxGraphicsPenInfo& Width(wxDouble width) wxGraphicsPenInfo& Width(wxDouble width)
{ m_width = width; return *this; } { m_width = width; return *this; }
wxGraphicsPenInfo& wxGraphicsPenInfo&
LinearGradient(wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, LinearGradient(wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour& c1, const wxColour& c2, const wxColour& c1, const wxColour& c2,
const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix) const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix)
{ {
m_gradientType = wxGRADIENT_LINEAR; m_gradientType = wxGRADIENT_LINEAR;
m_x1 = x1; m_x1 = x1;
m_y1 = y1; m_y1 = y1;
@@ -384,14 +384,14 @@ public:
m_stops.SetStartColour(c1); m_stops.SetStartColour(c1);
m_stops.SetEndColour(c2); m_stops.SetEndColour(c2);
m_matrix = matrix; m_matrix = matrix;
return *this; return *this;
} }
wxGraphicsPenInfo& wxGraphicsPenInfo&
LinearGradient(wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, LinearGradient(wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops, const wxGraphicsGradientStops& stops,
const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix) const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix)
{ {
m_gradientType = wxGRADIENT_LINEAR; m_gradientType = wxGRADIENT_LINEAR;
m_x1 = x1; m_x1 = x1;
m_y1 = y1; m_y1 = y1;
@@ -399,42 +399,42 @@ public:
m_y2 = y2; m_y2 = y2;
m_stops = stops; m_stops = stops;
m_matrix = matrix; m_matrix = matrix;
return *this; return *this;
} }
wxGraphicsPenInfo& wxGraphicsPenInfo&
RadialGradient(wxDouble startX, wxDouble startY, RadialGradient(wxDouble startX, wxDouble startY,
wxDouble endX, wxDouble endY, wxDouble radius, wxDouble endX, wxDouble endY, wxDouble radius,
const wxColour& oColor, const wxColour& cColor, const wxColour& oColor, const wxColour& cColor,
const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix) const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix)
{ {
m_gradientType = wxGRADIENT_RADIAL; m_gradientType = wxGRADIENT_RADIAL;
m_x1 = startX; m_x1 = startX;
m_y1 = startY; m_y1 = startY;
m_x2 = endX; m_x2 = endX;
m_y2 = endY; m_y2 = endY;
m_radius = radius; m_radius = radius;
m_stops.SetStartColour(oColor); m_stops.SetStartColour(oColor);
m_stops.SetEndColour(cColor); m_stops.SetEndColour(cColor);
m_matrix = matrix; m_matrix = matrix;
return *this; return *this;
} }
wxGraphicsPenInfo& wxGraphicsPenInfo&
RadialGradient(wxDouble startX, wxDouble startY, RadialGradient(wxDouble startX, wxDouble startY,
wxDouble endX, wxDouble endY, wxDouble endX, wxDouble endY,
wxDouble radius, const wxGraphicsGradientStops& stops, wxDouble radius, const wxGraphicsGradientStops& stops,
const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix) const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix)
{ {
m_gradientType = wxGRADIENT_RADIAL; m_gradientType = wxGRADIENT_RADIAL;
m_x1 = startX; m_x1 = startX;
m_y1 = startY; m_y1 = startY;
m_x2 = endX; m_x2 = endX;
m_y2 = endY; m_y2 = endY;
m_radius = radius; m_radius = radius;
m_stops = stops; m_stops = stops;
m_matrix = matrix; m_matrix = matrix;
return *this; return *this;
} }
// Accessors // Accessors

View File

@@ -745,7 +745,7 @@ wxGDIPlusPenBrushBaseData::CreateLinearGradientBrush(
} }
SetGradientStops(brush, stops); SetGradientStops(brush, stops);
m_brush = brush; m_brush = brush;
} }
void void
@@ -769,7 +769,7 @@ wxGDIPlusPenBrushBaseData::CreateRadialGradientBrush(
brush->SetSurroundColors(&col, &count); brush->SetSurroundColors(&col, &count);
// TODO: There doesn't seem to be an equivallent for SetWrapMode, so // TODO: There doesn't seem to be an equivallent for SetWrapMode, so
// the area outside of the gradient's radius is not getting painted. // the area outside of the gradient's radius is not getting painted.
// Apply the matrix if there is one // Apply the matrix if there is one
if ( !matrix.IsNull() ) if ( !matrix.IsNull() )

View File

@@ -1890,7 +1890,7 @@ void wxD2DPathData::Transform(const wxGraphicsMatrixData* matrix)
// constraints this can be fully done only if open figure was empty. // constraints this can be fully done only if open figure was empty.
// So, Transform() can be safely called if path doesn't contain the open // So, Transform() can be safely called if path doesn't contain the open
// sub-path or if open sub-path is empty. // sub-path or if open sub-path is empty.
// Close current geometry. // Close current geometry.
Flush(); Flush();
@@ -2427,15 +2427,15 @@ public:
const wxDouble y2; const wxDouble y2;
const wxGraphicsGradientStops stops; const wxGraphicsGradientStops stops;
const wxGraphicsMatrix matrix; const wxGraphicsMatrix matrix;
LinearGradientInfo(wxDouble& x1_, wxDouble& y1_, LinearGradientInfo(wxDouble& x1_, wxDouble& y1_,
wxDouble& x2_, wxDouble& y2_, wxDouble& x2_, wxDouble& y2_,
const wxGraphicsGradientStops& stops_, const wxGraphicsGradientStops& stops_,
const wxGraphicsMatrix& matrix_) const wxGraphicsMatrix& matrix_)
: x1(x1_), y1(y1_), x2(x2_), y2(y2_), stops(stops_), matrix(matrix_) {} : x1(x1_), y1(y1_), x2(x2_), y2(y2_), stops(stops_), matrix(matrix_) {}
}; };
wxD2DLinearGradientBrushResourceHolder(wxDouble& x1, wxDouble& y1, wxD2DLinearGradientBrushResourceHolder(wxDouble& x1, wxDouble& y1,
wxDouble& x2, wxDouble& y2, wxDouble& x2, wxDouble& y2,
const wxGraphicsGradientStops& stops, const wxGraphicsGradientStops& stops,
const wxGraphicsMatrix& matrix) const wxGraphicsMatrix& matrix)
: m_linearGradientInfo(x1, y1, x2, y2, stops, matrix) {} : m_linearGradientInfo(x1, y1, x2, y2, stops, matrix) {}
@@ -2444,23 +2444,21 @@ protected:
void DoAcquireResource() wxOVERRIDE void DoAcquireResource() wxOVERRIDE
{ {
wxD2DGradientStopsHelper helper(m_linearGradientInfo.stops, GetContext()); wxD2DGradientStopsHelper helper(m_linearGradientInfo.stops, GetContext());
ID2D1LinearGradientBrush *linearGradientBrush;
HRESULT hr = GetContext()->CreateLinearGradientBrush( HRESULT hr = GetContext()->CreateLinearGradientBrush(
D2D1::LinearGradientBrushProperties( D2D1::LinearGradientBrushProperties(
D2D1::Point2F(m_linearGradientInfo.x1, m_linearGradientInfo.y1), D2D1::Point2F(m_linearGradientInfo.x1, m_linearGradientInfo.y1),
D2D1::Point2F(m_linearGradientInfo.x2, m_linearGradientInfo.y2)), D2D1::Point2F(m_linearGradientInfo.x2, m_linearGradientInfo.y2)),
helper.GetGradientStopCollection(), helper.GetGradientStopCollection(),
&linearGradientBrush); &m_nativeResource);
wxCHECK_HRESULT_RET(hr); wxCHECK_HRESULT_RET(hr);
if (! m_linearGradientInfo.matrix.IsNull()) if (! m_linearGradientInfo.matrix.IsNull())
{ {
D2D1::Matrix3x2F matrix = wxGetD2DMatrixData(m_linearGradientInfo.matrix)->GetMatrix3x2F(); D2D1::Matrix3x2F matrix = wxGetD2DMatrixData(m_linearGradientInfo.matrix)->GetMatrix3x2F();
matrix.Invert(); matrix.Invert();
linearGradientBrush->SetTransform(matrix); m_nativeResource->SetTransform(matrix);
} }
m_nativeResource = linearGradientBrush;
} }
private: private:
const LinearGradientInfo m_linearGradientInfo; const LinearGradientInfo m_linearGradientInfo;
@@ -2478,17 +2476,17 @@ public:
const wxGraphicsGradientStops stops; const wxGraphicsGradientStops stops;
const wxGraphicsMatrix matrix; const wxGraphicsMatrix matrix;
RadialGradientInfo(wxDouble x1_, wxDouble y1_, RadialGradientInfo(wxDouble x1_, wxDouble y1_,
wxDouble x2_, wxDouble y2_, wxDouble x2_, wxDouble y2_,
wxDouble r, wxDouble r,
const wxGraphicsGradientStops& stops_, const wxGraphicsGradientStops& stops_,
const wxGraphicsMatrix& matrix_) const wxGraphicsMatrix& matrix_)
: x1(x1_), y1(y1_), x2(x2_), y2(y2_), radius(r), stops(stops_), matrix(matrix_) {} : x1(x1_), y1(y1_), x2(x2_), y2(y2_), radius(r), stops(stops_), matrix(matrix_) {}
}; };
wxD2DRadialGradientBrushResourceHolder(wxDouble& x1, wxDouble& y1, wxD2DRadialGradientBrushResourceHolder(wxDouble& x1, wxDouble& y1,
wxDouble& x2, wxDouble& y2, wxDouble& x2, wxDouble& y2,
wxDouble& r, wxDouble& r,
const wxGraphicsGradientStops& stops, const wxGraphicsGradientStops& stops,
const wxGraphicsMatrix& matrix) const wxGraphicsMatrix& matrix)
: m_radialGradientInfo(x1, y1, x2, y2, r, stops, matrix) {} : m_radialGradientInfo(x1, y1, x2, y2, r, stops, matrix) {}
@@ -2497,7 +2495,6 @@ protected:
void DoAcquireResource() wxOVERRIDE void DoAcquireResource() wxOVERRIDE
{ {
wxD2DGradientStopsHelper helper(m_radialGradientInfo.stops, GetContext()); wxD2DGradientStopsHelper helper(m_radialGradientInfo.stops, GetContext());
ID2D1RadialGradientBrush *radialGradientBrush;
wxDouble xo = m_radialGradientInfo.x1 - m_radialGradientInfo.x2; wxDouble xo = m_radialGradientInfo.x1 - m_radialGradientInfo.x2;
wxDouble yo = m_radialGradientInfo.y1 - m_radialGradientInfo.y2; wxDouble yo = m_radialGradientInfo.y1 - m_radialGradientInfo.y2;
@@ -2508,16 +2505,15 @@ protected:
D2D1::Point2F(xo, yo), D2D1::Point2F(xo, yo),
m_radialGradientInfo.radius, m_radialGradientInfo.radius), m_radialGradientInfo.radius, m_radialGradientInfo.radius),
helper.GetGradientStopCollection(), helper.GetGradientStopCollection(),
&radialGradientBrush); &m_nativeResource);
wxCHECK_HRESULT_RET(hr); wxCHECK_HRESULT_RET(hr);
if (! m_radialGradientInfo.matrix.IsNull()) if (! m_radialGradientInfo.matrix.IsNull())
{ {
D2D1::Matrix3x2F matrix = wxGetD2DMatrixData(m_radialGradientInfo.matrix)->GetMatrix3x2F(); D2D1::Matrix3x2F matrix = wxGetD2DMatrixData(m_radialGradientInfo.matrix)->GetMatrix3x2F();
matrix.Invert(); matrix.Invert();
radialGradientBrush->SetTransform(matrix); m_nativeResource->SetTransform(matrix);
} }
m_nativeResource = radialGradientBrush;
} }
private: private:
@@ -2535,14 +2531,14 @@ public:
wxD2DBrushData(wxGraphicsRenderer* renderer); wxD2DBrushData(wxGraphicsRenderer* renderer);
void CreateLinearGradientBrush(wxDouble x1, wxDouble y1, void CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
wxDouble x2, wxDouble y2, wxDouble x2, wxDouble y2,
const wxGraphicsGradientStops& stops, const wxGraphicsGradientStops& stops,
const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix); const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix);
void CreateRadialGradientBrush(wxDouble startX, wxDouble startY, void CreateRadialGradientBrush(wxDouble startX, wxDouble startY,
wxDouble endX, wxDouble endY, wxDouble endX, wxDouble endY,
wxDouble radius, wxDouble radius,
const wxGraphicsGradientStops& stops, const wxGraphicsGradientStops& stops,
const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix); const wxGraphicsMatrix& matrix = wxNullGraphicsMatrix);