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/program.hxx"
30 #include "opengl/texture.hxx"
31 #include "opengl/RenderList.hxx"
36 class SalVirtualDevice
;
52 std::unique_ptr
<OpenGLTexture
> mpTexture
;
53 std::unique_ptr
<OpenGLTexture
> mpMask
;
56 class OpenGLFlushIdle
;
58 class VCL_DLLPUBLIC OpenGLSalGraphicsImpl
: public SalGraphicsImpl
60 friend class OpenGLTests
;
63 /// This context is solely for blitting maOffscreenTex
64 rtl::Reference
<OpenGLContext
> mpWindowContext
;
66 /// This context is whatever is most convenient to render
67 /// to maOffscreenTex with.
68 rtl::Reference
<OpenGLContext
> mpContext
;
70 SalGraphics
& mrParent
;
71 /// Pointer to the SalFrame or SalVirtualDevice
72 SalGeometryProvider
* mpProvider
;
73 OpenGLProgram
* mpProgram
;
75 /// This idle handler is used to swap buffers after rendering.
76 std::unique_ptr
<OpenGLFlushIdle
> mpFlush
;
79 vcl::Region maClipRegion
;
85 bool mbAcquiringOpenGLContext
;
88 * All rendering happens to this off-screen texture. For
89 * non-virtual devices, ie. windows - we will blit it and
92 OpenGLTexture maOffscreenTex
;
97 bool mProgramIsSolidColor
;
99 sal_uInt32 mnDrawCount
;
100 sal_uInt32 mnDrawCountAtFlush
;
101 Color mProgramSolidColor
;
102 double mProgramSolidTransparency
;
104 std::unique_ptr
<RenderList
> mpRenderList
;
106 void ImplInitClipRegion();
107 void ImplSetClipBit( const vcl::Region
& rClip
, GLuint nMask
);
108 void ImplDrawLineAA( double nX1
, double nY1
, double nX2
, double nY2
, bool edge
);
109 void CheckOffscreenTexture();
111 void ApplyProgramMatrices(float fPixelOffset
= 0.0);
114 bool UseProgram( const OUString
& rVertexShader
, const OUString
& rFragmentShader
, const OString
& preamble
= "" );
115 bool UseSolid( Color nColor
, sal_uInt8 nTransparency
);
116 bool UseSolid( Color nColor
, double fTransparency
);
117 bool UseSolid( Color nColor
);
119 bool UseLine(Color nColor
, double fTransparency
, GLfloat fLineWidth
, bool bUseAA
);
120 void UseLine(GLfloat fLineWidth
, bool bUseAA
);
122 bool UseInvert(SalInvert nFlags
);
124 void DrawConvexPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, bool blockAA
= false );
125 void DrawConvexPolygon( const tools::Polygon
& rPolygon
, bool blockAA
);
126 void DrawTrapezoid( const basegfx::B2DTrapezoid
& trapezoid
, bool blockAA
);
127 void DrawRect( long nX
, long nY
, long nWidth
, long nHeight
);
128 void DrawRect( const tools::Rectangle
& rRect
);
129 void DrawPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
);
130 void DrawLineSegment(float x1
, float y1
, float x2
, float y2
);
131 void DrawPolyPolygon( const basegfx::B2DPolyPolygon
& rPolyPolygon
, bool blockAA
= false );
132 void DrawRegionBand( const RegionBand
& rRegion
);
133 void DrawTextureRect( const SalTwoRect
& rPosAry
);
134 void DrawTexture( OpenGLTexture
& rTexture
, const SalTwoRect
& rPosAry
, bool bInverted
= false );
135 void DrawTransformedTexture( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, const basegfx::B2DPoint
& rNull
, const basegfx::B2DPoint
& rX
, const basegfx::B2DPoint
& rY
);
136 void DrawAlphaTexture( OpenGLTexture
& rTexture
, const SalTwoRect
& rPosAry
, bool bInverted
, bool pPremultiplied
);
137 void DrawTextureDiff( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, const SalTwoRect
& rPosAry
, bool bInverted
);
138 void DrawTextureWithMask( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, const SalTwoRect
& rPosAry
);
139 void DrawBlendedTexture( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, OpenGLTexture
& rAlpha
, const SalTwoRect
& rPosAry
);
140 void DrawMask( OpenGLTexture
& rTexture
, Color nMaskColor
, const SalTwoRect
& rPosAry
);
141 void DrawLinearGradient( const Gradient
& rGradient
, const tools::Rectangle
& rRect
);
142 void DrawAxialGradient( const Gradient
& rGradient
, const tools::Rectangle
& rRect
);
143 void DrawRadialGradient( const Gradient
& rGradient
, const tools::Rectangle
& rRect
);
144 void DeferredTextDraw(OpenGLTexture
const & rTexture
, const Color nMaskColor
, const SalTwoRect
& rPosAry
);
146 void FlushDeferredDrawing();
147 void FlushLinesOrTriangles(DrawShaderType eType
, RenderParameters
const & rParameters
);
150 // get the width of the device
151 GLfloat
GetWidth() const { return mpProvider
? mpProvider
->GetWidth() : 1; }
153 // get the height of the device
154 GLfloat
GetHeight() const { return mpProvider
? mpProvider
->GetHeight() : 1; }
157 * check whether this instance is used for offscreen (Virtual Device)
158 * rendering ie. does it need its own context.
160 bool IsOffscreen() const { return mpProvider
== nullptr || mpProvider
->IsOffScreen(); }
162 /// Oddly not all operations obey the XOR option.
163 enum XOROption
{ IGNORE_XOR
, IMPLEMENT_XOR
};
165 // initialize pre-draw state
166 void InitializePreDrawState(XOROption eOpt
);
168 // operations to do before painting
169 void PreDraw(XOROption eOpt
= IGNORE_XOR
);
171 // operations to do after painting
174 void PostBatchDraw();
177 bool AcquireContext(bool bForceCreate
= false);
178 void ReleaseContext();
180 /// create a new context for rendering to the underlying window
181 virtual rtl::Reference
<OpenGLContext
> CreateWinContext() = 0;
183 /// check whether the given context can be used for off-screen rendering
184 static bool UseContext( const rtl::Reference
<OpenGLContext
> &pContext
)
186 return pContext
->isInitialized() && // not released by the OS etc.
187 pContext
->isVCLOnly();
191 OpenGLSalGraphicsImpl(SalGraphics
& pParent
, SalGeometryProvider
*pProvider
);
192 virtual ~OpenGLSalGraphicsImpl () override
;
194 rtl::Reference
<OpenGLContext
> GetOpenGLContext();
196 virtual void Init() override
;
198 virtual void DeInit() override
;
200 virtual void freeResources() override
;
202 const vcl::Region
& getClipRegion() const;
203 virtual bool setClipRegion( const vcl::Region
& ) override
;
206 // get the depth of the device
207 virtual sal_uInt16
GetBitCount() const override
;
209 // get the width of the device
210 virtual long GetGraphicsWidth() const override
;
212 // set the clip region to empty
213 virtual void ResetClipRegion() override
;
215 // set the line color to transparent (= don't draw lines)
217 virtual void SetLineColor() override
;
219 // set the line color to a specific color
220 virtual void SetLineColor( Color nColor
) override
;
222 // set the fill color to transparent (= don't fill)
223 virtual void SetFillColor() override
;
225 // set the fill color to a specific color, shapes will be
226 // filled accordingly
227 virtual void SetFillColor( Color nColor
) override
;
229 // enable/disable XOR drawing
230 virtual void SetXORMode( bool bSet
, bool bInvertOnly
) override
;
232 // set line color for raster operations
233 virtual void SetROPLineColor( SalROPColor nROPColor
) override
;
235 // set fill color for raster operations
236 virtual void SetROPFillColor( SalROPColor nROPColor
) override
;
238 // draw --> LineColor and FillColor and RasterOp and ClipRegion
239 virtual void drawPixel( long nX
, long nY
) override
;
240 virtual void drawPixel( long nX
, long nY
, Color nColor
) override
;
242 virtual void drawLine( long nX1
, long nY1
, long nX2
, long nY2
) override
;
244 virtual void drawRect( long nX
, long nY
, long nWidth
, long nHeight
) override
;
246 virtual void drawPolyLine( sal_uInt32 nPoints
, const SalPoint
* pPtAry
) override
;
248 virtual void drawPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
) override
;
250 virtual void drawPolyPolygon( sal_uInt32 nPoly
, const sal_uInt32
* pPoints
, PCONSTSALPOINT
* pPtAry
) override
;
252 virtual bool drawPolyPolygon(
253 const basegfx::B2DHomMatrix
& rObjectToDevice
,
254 const basegfx::B2DPolyPolygon
&,
255 double fTransparency
) override
;
257 virtual bool drawPolyLine(
258 const basegfx::B2DHomMatrix
& rObjectToDevice
,
259 const basegfx::B2DPolygon
&,
260 double fTransparency
,
261 const basegfx::B2DVector
& rLineWidths
,
262 basegfx::B2DLineJoin
,
263 css::drawing::LineCap
,
264 double fMiterMinimumAngle
,
265 bool bPixelSnapHairline
) override
;
267 virtual bool drawPolyLineBezier(
269 const SalPoint
* pPtAry
,
270 const PolyFlags
* pFlgAry
) override
;
272 virtual bool drawPolygonBezier(
274 const SalPoint
* pPtAry
,
275 const PolyFlags
* pFlgAry
) override
;
277 virtual bool drawPolyPolygonBezier(
279 const sal_uInt32
* pPoints
,
280 const SalPoint
* const* pPtAry
,
281 const PolyFlags
* const* pFlgAry
) override
;
283 // CopyArea --> No RasterOp, but ClipRegion
284 virtual void copyArea(
285 long nDestX
, long nDestY
,
286 long nSrcX
, long nSrcY
,
287 long nSrcWidth
, long nSrcHeight
,
288 bool bWindowInvalidate
) override
;
290 // CopyBits and DrawBitmap --> RasterOp and ClipRegion
291 // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
292 void DoCopyBits(const SalTwoRect
& rPosAry
, OpenGLSalGraphicsImpl
&rSrcImpl
);
294 virtual bool blendBitmap(
296 const SalBitmap
& rBitmap
) override
;
298 virtual bool blendAlphaBitmap(
300 const SalBitmap
& rSrcBitmap
,
301 const SalBitmap
& rMaskBitmap
,
302 const SalBitmap
& rAlphaBitmap
) override
;
304 virtual void drawBitmap( const SalTwoRect
& rPosAry
, const SalBitmap
& rSalBitmap
) override
;
306 virtual void drawBitmap(
307 const SalTwoRect
& rPosAry
,
308 const SalBitmap
& rSalBitmap
,
309 const SalBitmap
& rMaskBitmap
) override
;
311 virtual void drawMask(
312 const SalTwoRect
& rPosAry
,
313 const SalBitmap
& rSalBitmap
,
314 Color nMaskColor
) override
;
316 virtual std::shared_ptr
<SalBitmap
> getBitmap( long nX
, long nY
, long nWidth
, long nHeight
) override
;
318 virtual Color
getPixel( long nX
, long nY
) override
;
320 // invert --> ClipRegion (only Windows or VirDevs)
323 long nWidth
, long nHeight
,
324 SalInvert nFlags
) override
;
326 virtual void invert( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, SalInvert nFlags
) override
;
328 virtual bool drawEPS(
330 long nWidth
, long nHeight
,
332 sal_uInt32 nSize
) override
;
334 /** Render bitmap with alpha channel
337 Source bitmap to blit
340 Alpha channel to use for blitting
342 @return true, if the operation succeeded, and false
343 otherwise. In this case, clients should try to emulate alpha
344 compositing themselves
346 virtual bool drawAlphaBitmap(
348 const SalBitmap
& rSourceBitmap
,
349 const SalBitmap
& rAlphaBitmap
) override
;
351 /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
352 virtual bool drawTransformedBitmap(
353 const basegfx::B2DPoint
& rNull
,
354 const basegfx::B2DPoint
& rX
,
355 const basegfx::B2DPoint
& rY
,
356 const SalBitmap
& rSourceBitmap
,
357 const SalBitmap
* pAlphaBitmap
) override
;
359 /** Render solid rectangle with given transparency
361 @param nX Top left coordinate of rectangle
363 @param nY Bottom right coordinate of rectangle
365 @param nWidth Width of rectangle
367 @param nHeight Height of rectangle
369 @param nTransparency Transparency value (0-255) to use. 0 blits and opaque, 255 a
370 fully transparent rectangle
372 @returns true if successfully drawn, false if not able to draw rectangle
374 virtual bool drawAlphaRect(
376 long nWidth
, long nHeight
,
377 sal_uInt8 nTransparency
) override
;
379 virtual bool drawGradient(const tools::PolyPolygon
& rPolygon
, const Gradient
& rGradient
) override
;
381 /// queue an idle flush of contents of the back-buffer to the screen
385 /// do flush of contents of the back-buffer to the screen & swap.
391 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */