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/RenderList.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
;
86 bool mbAcquiringOpenGLContext
;
89 * All rendering happens to this off-screen texture. For
90 * non-virtual devices, ie. windows - we will blit it and
93 OpenGLTexture maOffscreenTex
;
98 bool mProgramIsSolidColor
;
100 sal_uInt32 mnDrawCount
;
101 sal_uInt32 mnDrawCountAtFlush
;
102 SalColor mProgramSolidColor
;
103 double mProgramSolidTransparency
;
105 std::unique_ptr
<RenderList
> mpRenderList
;
107 void ImplInitClipRegion();
108 void ImplSetClipBit( const vcl::Region
& rClip
, GLuint nMask
);
109 void ImplDrawLineAA( double nX1
, double nY1
, double nX2
, double nY2
, bool edge
);
110 bool CheckOffscreenTexture();
112 void ApplyProgramMatrices(float fPixelOffset
= 0.0);
115 bool UseProgram( const OUString
& rVertexShader
, const OUString
& rFragmentShader
, const OString
& preamble
= "" );
116 bool UseSolid( SalColor nColor
, sal_uInt8 nTransparency
);
117 bool UseSolid( SalColor nColor
, double fTransparency
);
118 bool UseSolid( SalColor nColor
);
120 bool UseLine(SalColor nColor
, double fTransparency
, GLfloat fLineWidth
, bool bUseAA
);
121 bool UseLine(GLfloat fLineWidth
, bool bUseAA
);
123 bool UseInvert(SalInvert nFlags
);
125 void DrawConvexPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, bool blockAA
= false );
126 void DrawConvexPolygon( const tools::Polygon
& rPolygon
, bool blockAA
);
127 void DrawTrapezoid( const basegfx::B2DTrapezoid
& trapezoid
, bool blockAA
);
128 void DrawRect( long nX
, long nY
, long nWidth
, long nHeight
);
129 void DrawRect( const Rectangle
& rRect
);
130 void DrawPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
);
131 void DrawLineSegment(float x1
, float y1
, float x2
, float y2
);
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
, bool pPremultiplied
);
138 void DrawTextureDiff( OpenGLTexture
& rTexture
, OpenGLTexture
& rMask
, const SalTwoRect
& rPosAry
, bool bInverted
);
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
);
147 void FlushDeferredDrawing();
148 bool FlushLinesOrTriangles(DrawShaderType eType
, RenderParameters
& rParameters
);
151 // get the width of the device
152 GLfloat
GetWidth() const { return mpProvider
? mpProvider
->GetWidth() : 1; }
154 // get the height of the device
155 GLfloat
GetHeight() const { return mpProvider
? mpProvider
->GetHeight() : 1; }
158 * check whether this instance is used for offscreen (Virtual Device)
159 * rendering ie. does it need its own context.
161 bool IsOffscreen() const { return mpProvider
== nullptr || mpProvider
->IsOffScreen(); }
163 /// Oddly not all operations obey the XOR option.
164 enum XOROption
{ IGNORE_XOR
, IMPLEMENT_XOR
};
166 // initialize pre-draw state
167 void InitializePreDrawState(XOROption eOpt
);
169 // operations to do before painting
170 void PreDraw(XOROption eOpt
= IGNORE_XOR
);
172 // operations to do after painting
175 void PostBatchDraw();
178 bool AcquireContext(bool bForceCreate
= false);
179 bool ReleaseContext();
181 /// create a new context for rendering to the underlying window
182 virtual rtl::Reference
<OpenGLContext
> CreateWinContext() = 0;
184 /// check whether the given context can be used for off-screen rendering
185 static bool UseContext( const rtl::Reference
<OpenGLContext
> &pContext
)
187 return pContext
->isInitialized() && // not released by the OS etc.
188 pContext
->isVCLOnly();
192 OpenGLSalGraphicsImpl(SalGraphics
& pParent
, SalGeometryProvider
*pProvider
);
193 virtual ~OpenGLSalGraphicsImpl () override
;
195 rtl::Reference
<OpenGLContext
> GetOpenGLContext();
197 virtual void Init() override
;
199 virtual void DeInit() override
;
201 virtual void freeResources() override
;
203 const vcl::Region
& getClipRegion() const;
204 virtual bool setClipRegion( const vcl::Region
& ) override
;
207 // get the depth of the device
208 virtual sal_uInt16
GetBitCount() const override
;
210 // get the width of the device
211 virtual long GetGraphicsWidth() const override
;
213 // set the clip region to empty
214 virtual void ResetClipRegion() override
;
216 // set the line color to transparent (= don't draw lines)
218 virtual void SetLineColor() override
;
220 // set the line color to a specific color
221 virtual void SetLineColor( SalColor nSalColor
) override
;
223 // set the fill color to transparent (= don't fill)
224 virtual void SetFillColor() override
;
226 // set the fill color to a specific color, shapes will be
227 // filled accordingly
228 virtual void SetFillColor( SalColor nSalColor
) override
;
230 // enable/disable XOR drawing
231 virtual void SetXORMode( bool bSet
) override
;
233 // set line color for raster operations
234 virtual void SetROPLineColor( SalROPColor nROPColor
) override
;
236 // set fill color for raster operations
237 virtual void SetROPFillColor( SalROPColor nROPColor
) override
;
239 // draw --> LineColor and FillColor and RasterOp and ClipRegion
240 virtual void drawPixel( long nX
, long nY
) override
;
241 virtual void drawPixel( long nX
, long nY
, SalColor nSalColor
) override
;
243 virtual void drawLine( long nX1
, long nY1
, long nX2
, long nY2
) override
;
245 virtual void drawRect( long nX
, long nY
, long nWidth
, long nHeight
) override
;
247 virtual void drawPolyLine( sal_uInt32 nPoints
, SalPoint
* pPtAry
) override
;
249 virtual void drawPolygon( sal_uInt32 nPoints
, const SalPoint
* pPtAry
) override
;
251 virtual void drawPolyPolygon( sal_uInt32 nPoly
, const sal_uInt32
* pPoints
, PCONSTSALPOINT
* pPtAry
) override
;
252 virtual bool drawPolyPolygon( const basegfx::B2DPolyPolygon
&, double fTransparency
) override
;
254 virtual bool drawPolyLine(
255 const basegfx::B2DPolygon
&,
256 double fTransparency
,
257 const basegfx::B2DVector
& rLineWidths
,
258 basegfx::B2DLineJoin
,
259 css::drawing::LineCap
,
260 double fMiterMinimumAngle
) override
;
262 virtual bool drawPolyLineBezier(
264 const SalPoint
* pPtAry
,
265 const PolyFlags
* pFlgAry
) override
;
267 virtual bool drawPolygonBezier(
269 const SalPoint
* pPtAry
,
270 const PolyFlags
* pFlgAry
) override
;
272 virtual bool drawPolyPolygonBezier(
274 const sal_uInt32
* pPoints
,
275 const SalPoint
* const* pPtAry
,
276 const PolyFlags
* const* pFlgAry
) override
;
278 // CopyArea --> No RasterOp, but ClipRegion
279 virtual void copyArea(
280 long nDestX
, long nDestY
,
281 long nSrcX
, long nSrcY
,
282 long nSrcWidth
, long nSrcHeight
,
283 bool bWindowInvalidate
) override
;
285 // CopyBits and DrawBitmap --> RasterOp and ClipRegion
286 // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
287 void DoCopyBits(const SalTwoRect
& rPosAry
, OpenGLSalGraphicsImpl
&rSrcImpl
);
289 virtual bool blendBitmap(
291 const SalBitmap
& rBitmap
) override
;
293 virtual bool blendAlphaBitmap(
295 const SalBitmap
& rSrcBitmap
,
296 const SalBitmap
& rMaskBitmap
,
297 const SalBitmap
& rAlphaBitmap
) override
;
299 virtual void drawBitmap( const SalTwoRect
& rPosAry
, const SalBitmap
& rSalBitmap
) override
;
301 virtual void drawBitmap(
302 const SalTwoRect
& rPosAry
,
303 const SalBitmap
& rSalBitmap
,
304 const SalBitmap
& rMaskBitmap
) override
;
306 virtual void drawMask(
307 const SalTwoRect
& rPosAry
,
308 const SalBitmap
& rSalBitmap
,
309 SalColor nMaskColor
) override
;
311 virtual SalBitmap
* getBitmap( long nX
, long nY
, long nWidth
, long nHeight
) override
;
313 virtual SalColor
getPixel( long nX
, long nY
) override
;
315 // invert --> ClipRegion (only Windows or VirDevs)
318 long nWidth
, long nHeight
,
319 SalInvert nFlags
) override
;
321 virtual void invert( sal_uInt32 nPoints
, const SalPoint
* pPtAry
, SalInvert nFlags
) override
;
323 virtual bool drawEPS(
325 long nWidth
, long nHeight
,
327 sal_uLong nSize
) override
;
329 /** Render bitmap with alpha channel
332 Source bitmap to blit
335 Alpha channel to use for blitting
337 @return true, if the operation succeeded, and false
338 otherwise. In this case, clients should try to emulate alpha
339 compositing themselves
341 virtual bool drawAlphaBitmap(
343 const SalBitmap
& rSourceBitmap
,
344 const SalBitmap
& rAlphaBitmap
) override
;
346 /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
347 virtual bool drawTransformedBitmap(
348 const basegfx::B2DPoint
& rNull
,
349 const basegfx::B2DPoint
& rX
,
350 const basegfx::B2DPoint
& rY
,
351 const SalBitmap
& rSourceBitmap
,
352 const SalBitmap
* pAlphaBitmap
) override
;
354 /** Render solid rectangle with given transparency
356 @param nX Top left coordinate of rectangle
358 @param nY Bottom right coordinate of rectangle
360 @param nWidth Width of rectangle
362 @param nHeight Height of rectangle
364 @param nTransparency Transparency value (0-255) to use. 0 blits and opaque, 255 a
365 fully transparent rectangle
367 @returns true if successfully drawn, false if not able to draw rectangle
369 virtual bool drawAlphaRect(
371 long nWidth
, long nHeight
,
372 sal_uInt8 nTransparency
) override
;
374 virtual bool drawGradient(const tools::PolyPolygon
& rPolygon
, const Gradient
& rGradient
) override
;
376 /// queue an idle flush of contents of the back-buffer to the screen
380 /// do flush of contents of the back-buffer to the screen & swap.
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */