1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_VCL_OPENGLGDIIMPL_HXX
21 #define INCLUDED_VCL_OPENGLGDIIMPL_HXX
23 #include <vcl/dllapi.h>
24 #include <vcl/opengl/OpenGLContext.hxx>
26 #include "regionband.hxx"
27 #include "salgeom.hxx"
28 #include "salgdiimpl.hxx"
29 #include "opengl/framebuffer.hxx"
30 #include "opengl/program.hxx"
31 #include "opengl/texture.hxx"
32 #include "opengl/AccumulatedTextures.hxx"
37 class SalVirtualDevice
;
53 std::unique_ptr
<OpenGLTexture
> mpTexture
;
54 std::unique_ptr
<OpenGLTexture
> mpMask
;
57 class OpenGLFlushIdle
;
59 class VCL_DLLPUBLIC OpenGLSalGraphicsImpl
: public SalGraphicsImpl
61 friend class OpenGLTests
;
64 /// This context is solely for blitting maOffscreenTex
65 rtl::Reference
<OpenGLContext
> mpWindowContext
;
67 /// This context is whatever is most convenient to render
68 /// to maOffscreenTex with.
69 rtl::Reference
<OpenGLContext
> mpContext
;
71 SalGraphics
& mrParent
;
72 /// Pointer to the SalFrame or SalVirtualDevice
73 SalGeometryProvider
* mpProvider
;
74 OpenGLProgram
* mpProgram
;
76 /// This idle handler is used to swap buffers after rendering.
77 OpenGLFlushIdle
*mpFlush
;
80 vcl::Region maClipRegion
;
87 * All rendering happens to this off-screen texture. For
88 * non-virtual devices, ie. windows - we will blit it and
91 OpenGLTexture maOffscreenTex
;
96 bool mProgramIsSolidColor
;
98 sal_uInt32 mnDrawCount
;
99 sal_uInt32 mnDrawCountAtFlush
;
100 SalColor mProgramSolidColor
;
101 double mProgramSolidTransparency
;
103 std::unique_ptr
<AccumulatedTextures
> mpAccumulatedTextures
;
105 void ImplInitClipRegion();
106 void ImplSetClipBit( const vcl::Region
& rClip
, GLuint nMask
);
107 void ImplDrawLineAA( double nX1
, double nY1
, double nX2
, double nY2
, bool edge
= false );
108 bool CheckOffscreenTexture();
110 void ApplyProgramMatrices(float fPixelOffset
= 0.0);
113 bool UseProgram( const OUString
& rVertexShader
, const OUString
& rFragmentShader
, const OString
& preamble
= "" );
114 bool UseSolid( SalColor nColor
, sal_uInt8 nTransparency
);
115 bool UseSolid( SalColor nColor
, double fTransparency
);
116 bool UseSolid( SalColor nColor
);
117 bool UseLine(SalColor nColor
, double fTransparency
, GLfloat fLineWidth
, bool bUseAA
);
119 bool UseInvert(SalInvert nFlags
);
121 void DrawPoint( long nX
, long nY
);
122 void DrawLine( double nX1
, double nY1
, double nX2
, double nY2
);
123 void DrawConvexPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, bool blockAA
= false );
124 void DrawConvexPolygon( const tools::Polygon
& rPolygon
, bool blockAA
= false );
125 void DrawTrapezoid( const basegfx::B2DTrapezoid
& trapezoid
, bool blockAA
= false );
126 void DrawRect( long nX
, long nY
, long nWidth
, long nHeight
);
127 void DrawRect( const Rectangle
& rRect
);
128 void DrawPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
);
129 void DrawLineSegment(float x1
, float y1
, float x2
, float y2
);
130 void DrawLineCap(float x1
, float y1
, float x2
, float y2
, css::drawing::LineCap eLineCap
, float fLineWidth
);
131 void DrawPolyLine( const basegfx::B2DPolygon
& rPolygon
, float fLineWidth
, basegfx::B2DLineJoin eLineJoin
, css::drawing::LineCap eLineCap
, float fMiterMinimumAngle
);
132 void DrawPolyPolygon( const basegfx::B2DPolyPolygon
& rPolyPolygon
, bool blockAA
= false );
133 void DrawRegionBand( const RegionBand
& rRegion
);
134 void DrawTextureRect( OpenGLTexture
& rTexture
, const SalTwoRect
& rPosAry
, bool bInverted
= false );
135 void DrawTexture( OpenGLTexture
& rTexture
, const SalTwoRect
& rPosAry
, bool bInverted
= false );
136 void DrawTransformedTexture( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, const basegfx::B2DPoint
& rNull
, const basegfx::B2DPoint
& rX
, const basegfx::B2DPoint
& rY
);
137 void DrawAlphaTexture( OpenGLTexture
& rTexture
, const SalTwoRect
& rPosAry
, bool bInverted
= false, bool pPremultiplied
= false );
138 void DrawTextureDiff( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, const SalTwoRect
& rPosAry
, bool bInverted
= false );
139 void DrawTextureWithMask( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, const SalTwoRect
& rPosAry
);
140 void DrawBlendedTexture( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, OpenGLTexture
& rAlpha
, const SalTwoRect
& rPosAry
);
141 void DrawMask( OpenGLTexture
& rTexture
, SalColor nMaskColor
, const SalTwoRect
& rPosAry
);
142 void DrawLinearGradient( const Gradient
& rGradient
, const Rectangle
& rRect
);
143 void DrawAxialGradient( const Gradient
& rGradient
, const Rectangle
& rRect
);
144 void DrawRadialGradient( const Gradient
& rGradient
, const Rectangle
& rRect
);
145 void DeferredTextDraw(OpenGLTexture
& rTexture
, const SalColor nMaskColor
, const SalTwoRect
& rPosAry
);
146 void FlushDeferredDrawing();
149 // get the width of the device
150 GLfloat
GetWidth() const { return mpProvider
? mpProvider
->GetWidth() : 1; }
152 // get the height of the device
153 GLfloat
GetHeight() const { return mpProvider
? mpProvider
->GetHeight() : 1; }
156 * check whether this instance is used for offscreen (Virtual Device)
157 * rendering ie. does it need its own context.
159 bool IsOffscreen() const { return mpProvider
== nullptr || mpProvider
->IsOffScreen(); }
161 /// Oddly not all operations obey the XOR option.
162 enum XOROption
{ IGNORE_XOR
, IMPLEMENT_XOR
};
164 // initialize pre-draw state
165 void InitializePreDrawState(XOROption eOpt
= IGNORE_XOR
);
167 // operations to do before painting
168 void PreDraw(XOROption eOpt
= IGNORE_XOR
);
170 // operations to do after painting
173 void PostBatchDraw();
176 bool AcquireContext(bool bForceCreate
= false);
177 bool ReleaseContext();
179 /// create a new context for rendering to the underlying window
180 virtual rtl::Reference
<OpenGLContext
> CreateWinContext() = 0;
182 /// check whether the given context can be used for off-screen rendering
183 static bool UseContext( const rtl::Reference
<OpenGLContext
> &pContext
)
185 return pContext
->isInitialized() && // not released by the OS etc.
186 pContext
->isVCLOnly();
190 OpenGLSalGraphicsImpl(SalGraphics
& pParent
, SalGeometryProvider
*pProvider
);
191 virtual ~OpenGLSalGraphicsImpl ();
193 rtl::Reference
<OpenGLContext
> GetOpenGLContext();
195 virtual void Init() override
;
197 virtual void DeInit() override
;
199 virtual void freeResources() override
;
201 const vcl::Region
& getClipRegion() const;
202 virtual bool setClipRegion( const vcl::Region
& ) override
;
205 // get the depth of the device
206 virtual sal_uInt16
GetBitCount() const override
;
208 // get the width of the device
209 virtual long GetGraphicsWidth() const override
;
211 // set the clip region to empty
212 virtual void ResetClipRegion() override
;
214 // set the line color to transparent (= don't draw lines)
216 virtual void SetLineColor() override
;
218 // set the line color to a specific color
219 virtual void SetLineColor( SalColor nSalColor
) override
;
221 // set the fill color to transparent (= don't fill)
222 virtual void SetFillColor() override
;
224 // set the fill color to a specific color, shapes will be
225 // filled accordingly
226 virtual void SetFillColor( SalColor nSalColor
) override
;
228 // enable/disable XOR drawing
229 virtual void SetXORMode( bool bSet
, bool bInvertOnly
) override
;
231 // set line color for raster operations
232 virtual void SetROPLineColor( SalROPColor nROPColor
) override
;
234 // set fill color for raster operations
235 virtual void SetROPFillColor( SalROPColor nROPColor
) override
;
237 // draw --> LineColor and FillColor and RasterOp and ClipRegion
238 virtual void drawPixel( long nX
, long nY
) override
;
239 virtual void drawPixel( long nX
, long nY
, SalColor nSalColor
) override
;
241 virtual void drawLine( long nX1
, long nY1
, long nX2
, long nY2
) override
;
243 virtual void drawRect( long nX
, long nY
, long nWidth
, long nHeight
) override
;
245 virtual void drawPolyLine( sal_uInt32 nPoints
, const SalPoint
* pPtAry
) override
;
247 virtual void drawPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
) override
;
249 virtual void drawPolyPolygon( sal_uInt32 nPoly
, const sal_uInt32
* pPoints
, PCONSTSALPOINT
* pPtAry
) override
;
250 virtual bool drawPolyPolygon( const basegfx::B2DPolyPolygon
&, double fTransparency
) override
;
252 virtual bool drawPolyLine(
253 const basegfx::B2DPolygon
&,
254 double fTransparency
,
255 const basegfx::B2DVector
& rLineWidths
,
256 basegfx::B2DLineJoin
,
257 css::drawing::LineCap
,
258 double fMiterMinimumAngle
) override
;
260 virtual bool drawPolyLineBezier(
262 const SalPoint
* pPtAry
,
263 const sal_uInt8
* pFlgAry
) override
;
265 virtual bool drawPolygonBezier(
267 const SalPoint
* pPtAry
,
268 const sal_uInt8
* pFlgAry
) override
;
270 virtual bool drawPolyPolygonBezier(
272 const sal_uInt32
* pPoints
,
273 const SalPoint
* const* pPtAry
,
274 const sal_uInt8
* const* pFlgAry
) override
;
276 // CopyArea --> No RasterOp, but ClipRegion
277 virtual void copyArea(
278 long nDestX
, long nDestY
,
279 long nSrcX
, long nSrcY
,
280 long nSrcWidth
, long nSrcHeight
,
281 bool bWindowInvalidate
) override
;
283 // CopyBits and DrawBitmap --> RasterOp and ClipRegion
284 // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
285 void DoCopyBits(const SalTwoRect
& rPosAry
, OpenGLSalGraphicsImpl
&rSrcImpl
);
287 virtual bool blendBitmap(
289 const SalBitmap
& rBitmap
) override
;
291 virtual bool blendAlphaBitmap(
293 const SalBitmap
& rSrcBitmap
,
294 const SalBitmap
& rMaskBitmap
,
295 const SalBitmap
& rAlphaBitmap
) override
;
297 virtual void drawBitmap( const SalTwoRect
& rPosAry
, const SalBitmap
& rSalBitmap
) override
;
299 virtual void drawBitmap(
300 const SalTwoRect
& rPosAry
,
301 const SalBitmap
& rSalBitmap
,
302 const SalBitmap
& rMaskBitmap
) override
;
304 virtual void drawMask(
305 const SalTwoRect
& rPosAry
,
306 const SalBitmap
& rSalBitmap
,
307 SalColor nMaskColor
) override
;
309 virtual SalBitmap
* getBitmap( long nX
, long nY
, long nWidth
, long nHeight
) override
;
311 virtual SalColor
getPixel( long nX
, long nY
) override
;
313 // invert --> ClipRegion (only Windows or VirDevs)
316 long nWidth
, long nHeight
,
317 SalInvert nFlags
) override
;
319 virtual void invert( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, SalInvert nFlags
) override
;
321 virtual bool drawEPS(
323 long nWidth
, long nHeight
,
325 sal_uLong nSize
) override
;
327 /** Render bitmap with alpha channel
330 Source bitmap to blit
333 Alpha channel to use for blitting
335 @return true, if the operation succeeded, and false
336 otherwise. In this case, clients should try to emulate alpha
337 compositing themselves
339 virtual bool drawAlphaBitmap(
341 const SalBitmap
& rSourceBitmap
,
342 const SalBitmap
& rAlphaBitmap
) override
;
344 /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
345 virtual bool drawTransformedBitmap(
346 const basegfx::B2DPoint
& rNull
,
347 const basegfx::B2DPoint
& rX
,
348 const basegfx::B2DPoint
& rY
,
349 const SalBitmap
& rSourceBitmap
,
350 const SalBitmap
* pAlphaBitmap
) override
;
352 /** Render solid rectangle with given transparency
354 @param nX Top left coordinate of rectangle
356 @param nY Bottom right coordinate of rectangle
358 @param nWidth Width of rectangle
360 @param nHeight Height of rectangle
362 @param nTransparency Transparency value (0-255) to use. 0 blits and opaque, 255 a
363 fully transparent rectangle
365 @returns true if successfully drawn, false if not able to draw rectangle
367 virtual bool drawAlphaRect(
369 long nWidth
, long nHeight
,
370 sal_uInt8 nTransparency
) override
;
372 virtual bool drawGradient(const tools::PolyPolygon
& rPolygon
, const Gradient
& rGradient
) override
;
374 /// queue an idle flush of contents of the back-buffer to the screen
378 /// do flush of contents of the back-buffer to the screen & swap.
384 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */