ScummVM API documentation
gfx_driver_base.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 //=============================================================================
23 //
24 // Implementation base for graphics driver
25 //
26 //=============================================================================
27 
28 #ifndef AGS_ENGINE_GFX_GFX_DRIVER_BASE_H
29 #define AGS_ENGINE_GFX_GFX_DRIVER_BASE_H
30 
31 #include "common/std/memory.h"
32 #include "common/std/map.h"
33 #include "common/std/vector.h"
34 #include "ags/engine/gfx/ddb.h"
35 #include "ags/shared/gfx/gfx_def.h"
36 #include "ags/engine/gfx/graphics_driver.h"
37 #include "ags/shared/util/scaling.h"
38 
39 namespace AGS3 {
40 namespace AGS {
41 namespace Engine {
42 
43 using Shared::Bitmap;
44 using Shared::PlaneScaling;
45 
46 // Sprite batch, defines viewport and an optional model transformation for the list of sprites
48  uint32_t Parent = UINT32_MAX;
49  // View rectangle for positioning and clipping, in resolution coordinates
50  // (this may be screen or game frame resolution, depending on circumstances)
51  Rect Viewport;
52  // Optional model transformation, to be applied to each sprite
53  SpriteTransform Transform;
54  // Optional flip, applied to the whole batch as the last transform
55  Shared::GraphicFlip Flip = Shared::kFlip_None;
56  // Optional bitmap to draw sprites upon. Used exclusively by the software rendering mode.
58 
59  SpriteBatchDesc() = default;
60  SpriteBatchDesc(uint32_t parent, const Rect viewport, const SpriteTransform & transform,
61  Shared::GraphicFlip flip = Shared::kFlip_None, PBitmap surface = nullptr)
62  : Parent(parent)
63  , Viewport(viewport)
64  , Transform(transform)
65  , Flip(flip)
66  , Surface(surface) {
67  }
68 };
69 
71 
72 // The single sprite entry in the render list
73 template<class T_DDB>
75  T_DDB *ddb = nullptr; // TODO: use shared pointer?
76  uint32_t node = 0; // sprite batch / scene node index
77  int x = 0, y = 0; // sprite position, in local batch / node coordinates
78  bool skip = false;
79 
80  SpriteDrawListEntry() = default;
81  SpriteDrawListEntry(T_DDB * ddb_, uint32_t node_, int x_, int y_)
82  : ddb(ddb_)
83  , node(node_)
84  , x(x_)
85  , y(y_)
86  , skip(false) {
87  }
88 };
89 
90 
91 // GraphicsDriverBase - is the parent class for all graphics drivers in AGS,
92 // that incapsulates the most common functionality.
94 public:
96 
97  bool IsModeSet() const override;
98  bool IsNativeSizeValid() const override;
99  bool IsRenderFrameValid() const override;
100  DisplayMode GetDisplayMode() const override;
101  Size GetNativeSize() const override;
102  Rect GetRenderDestination() const override;
103 
104  bool SetVsync(bool enabled) override;
105  bool GetVsync() const override;
106 
107  void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform,
108  Shared::GraphicFlip flip = Shared::kFlip_None, PBitmap surface = nullptr) override;
109  void EndSpriteBatch() override;
110  void ClearDrawLists() override;
111 
112  void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) override {
113  _pollingCallback = callback;
114  }
115  void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) override {
116  _drawScreenCallback = callback;
117  _drawPostScreenCallback = post_callback;
118  }
119  void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) override {
120  _initGfxCallback = callback;
121  }
122  void SetCallbackOnSpriteEvt(GFXDRV_CLIENTCALLBACKEVT callback) override {
123  _spriteEvtCallback = callback;
124  }
125 
126 protected:
127  // Special internal values, applied to DrawListEntry
128  static const intptr_t DRAWENTRY_STAGECALLBACK = 0x0;
129  static const intptr_t DRAWENTRY_FADE = 0x1;
130  static const intptr_t DRAWENTRY_TINT = 0x2;
131 
132  // Called after graphics driver was initialized for use for the first time
133  virtual void OnInit();
134  // Called just before graphics mode is going to be uninitialized and its
135  // resources released
136  virtual void OnUnInit();
137  // Called after new mode was successfully initialized
138  virtual void OnModeSet(const DisplayMode &mode);
139  // Called when the new native size is set
140  virtual void OnSetNativeRes(const GraphicResolution &native_res);
141  // Called before display mode is going to be released
142  virtual void OnModeReleased();
143  // Called when new render frame is set
144  virtual void OnSetRenderFrame(const Rect &dst_rect);
145  // Called when the new filter is set
146  virtual void OnSetFilter();
147 
148  // Try changing vsync setting; fills new current mode in vsync_res,
149  // returns whether the new setting was set successfully.
150  virtual bool SetVsyncImpl(bool vsync, bool &vsync_res) { return false; }
151 
152  // Initialize sprite batch and allocate necessary resources
153  virtual void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) = 0;
154  // Gets the index of a last draw entry (sprite)
155  virtual size_t GetLastDrawEntryIndex() = 0;
156  // Clears sprite lists
157  virtual void ResetAllBatches() = 0;
158 
159  void OnScalingChanged();
160 
161  DisplayMode _mode; // display mode settings
162  Rect _srcRect; // rendering source rect
163  int _srcColorDepth; // rendering source color depth (in bits per pixel)
164  Rect _dstRect; // rendering destination rect
165  Rect _filterRect; // filter scaling destination rect (before final scaling)
166  PlaneScaling _scaling; // native -> render dest coordinate transformation
167 
168  // Capability flags
169  bool _capsVsync = false; // is vsync available
170 
171  // Callbacks
172  GFXDRV_CLIENTCALLBACK _pollingCallback;
173  GFXDRV_CLIENTCALLBACK _drawScreenCallback;
174  GFXDRV_CLIENTCALLBACK _drawPostScreenCallback;
175  GFXDRV_CLIENTCALLBACKEVT _spriteEvtCallback;
176  GFXDRV_CLIENTCALLBACKINITGFX _initGfxCallback;
177 
178  // Sprite batch parameters
179  SpriteBatchDescs _spriteBatchDesc;
180  // The range of sprites in this sprite batch (counting nested sprites):
181  // the last of the previous batch, and the last of the current.
182  std::vector<std::pair<size_t, size_t>> _spriteBatchRange;
183  // The index of a currently filled sprite batch
184  size_t _actSpriteBatch;
185  // The index of a currently rendered sprite batch
186  // (or -1 / UINT32_MAX if we are outside of the render pass)
187  uint32_t _rendSpriteBatch;
188 };
189 
190 
191 
192 
193 // Parent class for the video memory DDBs
195 public:
196  int GetWidth() const override {
197  return _width;
198  }
199  int GetHeight() const override {
200  return _height;
201  }
202  int GetColorDepth() const override {
203  return _colDepth;
204  }
205 
206  int _width = 0, _height = 0;
207  int _colDepth = 0;
208  bool _hasAlpha = false; // has meaningful alpha channel
209  bool _opaque = false; // no mask color
210 
211 protected:
212  BaseDDB() {}
213  virtual ~BaseDDB() {}
214 };
215 
216 // A base parent for the otherwise opaque texture data object;
217 // TextureData refers to the pixel data itself, with no additional
218 // properties. It may be shared between multiple sprites if necessary.
219 struct TextureData {
220  uint32_t ID = UINT32_MAX;
221  bool RenderTarget = false; // replace with flags later
222  virtual ~TextureData() = default;
223 protected:
224  TextureData() = default;
225 };
226 
227 // Generic TextureTile base
228 struct TextureTile {
229  int x = 0, y = 0;
230  int width = 0, height = 0;
231 };
232 
233 
234 // VideoMemoryGraphicsDriver - is the parent class for the graphic drivers
235 // which drawing method is based on passing the sprite stack into GPU,
236 // rather than blitting to flat screen bitmap.
238 public:
240  ~VideoMemoryGraphicsDriver() override;
241 
242  bool UsesMemoryBackBuffer() override;
243  Bitmap *GetMemoryBackBuffer() override;
244  void SetMemoryBackBuffer(Bitmap *backBuffer) override;
245  Bitmap *GetStageBackBuffer(bool mark_dirty) override;
246  void SetStageBackBuffer(Bitmap *backBuffer) override;
247  bool GetStageMatrixes(RenderMatrixes &rm) override;
248  // Creates new texture using given parameters
249  IDriverDependantBitmap *CreateDDB(int width, int height, int color_depth, bool opaque) override = 0;
250  // Creates new texture and copy bitmap contents over
251  IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque = false) override;
252  // Get shared texture from cache, or create from bitmap and assign ID
253  IDriverDependantBitmap *GetSharedDDB(uint32_t sprite_id, Bitmap *bitmap, bool hasAlpha, bool opaque) override;
254  // Removes the shared texture reference, will force the texture to recreate next time
255  void ClearSharedDDB(uint32_t sprite_id) override;
256  // Updates shared texture data, but only if it is present in the cache
257  void UpdateSharedDDB(uint32_t sprite_id, Bitmap *bitmap, bool hasAlpha, bool opaque) override;
258  void DestroyDDB(IDriverDependantBitmap* ddb) override;
259 
260  // Sets stage screen parameters for the current batch.
261  void SetStageScreen(const Size &sz, int x = 0, int y = 0) override;
262 
263 protected:
264  // Create texture data with the given parameters
265  virtual TextureData *CreateTextureData(int width, int height, bool opaque, bool as_render_target = false) = 0;
266  // Update texture data from the given bitmap
267  virtual void UpdateTextureData(TextureData *txdata, Bitmap *bmp, bool opaque, bool hasAlpha) = 0;
268  // Create DDB using preexisting texture data
269  virtual IDriverDependantBitmap *CreateDDB(std::shared_ptr<TextureData> txdata,
270  int width, int height, int color_depth, bool opaque) = 0;
271  // Retrieve shared texture data object from the given DDB
272  virtual std::shared_ptr<TextureData> GetTextureData(IDriverDependantBitmap *ddb) = 0;
273  virtual void DestroyDDBImpl(IDriverDependantBitmap* ddb) = 0;
274 
275  // Stage screens are raw bitmap buffers meant to be sent to plugins on demand
276  // at certain drawing stages. If used at least once these buffers are then
277  // rendered as additional sprites in their respected order.
278  // Presets a stage screen with the given position (size is obligatory, offsets not).
279  void SetStageScreen(size_t index, const Size &sz, int x = 0, int y = 0);
280  // Returns a raw bitmap for the given stage screen.
281  Bitmap *GetStageScreenRaw(size_t index);
282  // Updates and returns a DDB for the given stage screen, and optional x,y position;
283  // clears the raw bitmap after copying to the texture.
284  IDriverDependantBitmap *UpdateStageScreenDDB(size_t index, int &x, int &y);
285  // Disposes all the stage screen raw bitmaps and DDBs.
286  void DestroyAllStageScreens();
287  // Use engine callback to pass a render event;
288  // returns a DDB if anything was drawn onto the current stage screen
289  // (in which case it also fills optional x,y position),
290  // or nullptr if this entry should be skipped.
291  IDriverDependantBitmap *DoSpriteEvtCallback(int evt, int data, int &x, int &y);
292 
293  // Prepare and get fx item from the pool
294  IDriverDependantBitmap *MakeFx(int r, int g, int b);
295  // Resets fx pool counter
296  void ResetFxPool();
297  // Disposes all items in the fx pool
298  void DestroyFxPool();
299 
300  // Prepares bitmap to be applied to the texture, copies pixels to the provided buffer
301  void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
302  char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering);
303  // Same but optimized for opaque source bitmaps which ignore transparent "mask color"
304  void BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
305  char *dst_ptr, const int dst_pitch);
306 
307  // Stage virtual screen is used to let plugins draw custom graphics
308  // in between render stages (between room and GUI, after GUI, and so on)
309  PBitmap _stageVirtualScreen;
310  IDriverDependantBitmap *_stageVirtualScreenDDB;
311  // Stage matrixes are used to let plugins with hardware acceleration know model matrix;
312  // these matrixes are filled compatible with each given renderer
313  RenderMatrixes _stageMatrixes;
314 
315  // Color component shifts in video bitmap format (set by implementations)
316  int _vmem_a_shift_32;
317  int _vmem_r_shift_32;
318  int _vmem_g_shift_32;
319  int _vmem_b_shift_32;
320 
321 private:
322  // Stage virtual screens are used to let plugins draw custom graphics
323  // in between render stages (between room and GUI, after GUI, and so on).
324  // TODO: possibly may be optimized further by having only 1 bitmap/ddb
325  // pair, and subbitmaps for raw drawing on separate stages.
326  struct StageScreen {
327  Rect Position; // bitmap size and pos preset (bitmap may be created later)
329  IDriverDependantBitmap *DDB = nullptr;
330  };
331  std::vector<StageScreen> _stageScreens;
332  // Flag which indicates whether stage screen was drawn upon during engine
333  // callback and has to be inserted into sprite stack.
334  bool _stageScreenDirty;
335 
336  // Fx quads pool (for screen overlay effects)
337  struct ScreenFx {
338  Bitmap *Raw = nullptr;
339  IDriverDependantBitmap *DDB = nullptr;
340  int Red = -1;
341  int Green = -1;
342  int Blue = -1;
343  };
344  std::vector<ScreenFx> _fxPool;
345  size_t _fxIndex; // next free pool item
346 
347  // Texture short-term cache:
348  // - caches textures while they are in the immediate use;
349  // - this lets to share same texture data among multiple sprites on screen.
350  // TextureCacheItem stores weak references to the existing texture tiles,
351  // identified by an arbitrary uint32 number.
352  // TODO: a curious topic to consider: reuse released TextureData for
353  // textures of the same size (research potential performance impact).
354  struct TextureCacheItem {
355  GraphicResolution Res;
357  TextureCacheItem() = default;
358  TextureCacheItem(std::shared_ptr<TextureData> data, const GraphicResolution &res)
359  : Data(data), Res(res) {}
360  };
362 };
363 
364 } // namespace Engine
365 } // namespace AGS
366 } // namespace AGS3
367 
368 #endif
Definition: achievements_tables.h:27
Definition: graphics_driver.h:70
Definition: allegro_bitmap.h:44
Definition: ptr.h:115
Definition: gfx_driver_base.h:237
Definition: gfx_driver_base.h:194
Definition: gfx_defines.h:60
Definition: ptr.h:572
Definition: viewport.h:128
Definition: gfx_driver_base.h:47
Definition: graphics_driver.h:98
Definition: surface.h:329
Definition: scaling.h:108
Definition: geometry.h:215
Definition: geometry.h:144
Definition: gfx_defines.h:33
Definition: gfx_driver_base.h:219
Definition: gfx_driver_base.h:93
Definition: gfx_driver_base.h:228
Definition: ptr.h:159
Definition: engine.h:143
Definition: graphics_driver.h:85
Definition: ags.h:40
Definition: gfx_driver_base.h:74