ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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  // Optional filter flags; this lets to filter certain batches out during some operations,
59  // such as fading effects or making screenshots.
60  uint32_t FilterFlags = 0u;
61 
62  SpriteBatchDesc() = default;
63  SpriteBatchDesc(uint32_t parent, const Rect viewport, const SpriteTransform & transform,
64  Shared::GraphicFlip flip = Shared::kFlip_None, PBitmap surface = nullptr, uint32_t filter_flags = 0)
65  : Parent(parent)
66  , Viewport(viewport)
67  , Transform(transform)
68  , Flip(flip)
69  , Surface(surface)
70  , FilterFlags(filter_flags) {
71  }
72 };
73 
75 
76 // The single sprite entry in the render list
77 template<class T_DDB>
79  T_DDB *ddb = nullptr; // TODO: use shared pointer?
80  uint32_t node = 0; // sprite batch / scene node index
81  int x = 0, y = 0; // sprite position, in local batch / node coordinates
82  bool skip = false;
83 
84  SpriteDrawListEntry() = default;
85  SpriteDrawListEntry(T_DDB * ddb_, uint32_t node_, int x_, int y_)
86  : ddb(ddb_)
87  , node(node_)
88  , x(x_)
89  , y(y_)
90  , skip(false) {
91  }
92 };
93 
94 
95 // GraphicsDriverBase - is the parent class for all graphics drivers in AGS,
96 // that incapsulates the most common functionality.
98 public:
100 
101  bool IsModeSet() const override;
102  bool IsNativeSizeValid() const override;
103  bool IsRenderFrameValid() const override;
104  DisplayMode GetDisplayMode() const override;
105  Size GetNativeSize() const override;
106  Rect GetRenderDestination() const override;
107 
108  bool SetVsync(bool enabled) override;
109  bool GetVsync() const override;
110 
111  void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform,
112  Shared::GraphicFlip flip = Shared::kFlip_None, PBitmap surface = nullptr,
113  uint32_t filter_flags = 0) override;
114  void EndSpriteBatch() override;
115  void ClearDrawLists() override;
116 
117  void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) override {
118  _pollingCallback = callback;
119  }
120  void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) override {
121  _drawScreenCallback = callback;
122  _drawPostScreenCallback = post_callback;
123  }
124  void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) override {
125  _initGfxCallback = callback;
126  }
127  void SetCallbackOnSpriteEvt(GFXDRV_CLIENTCALLBACKEVT callback) override {
128  _spriteEvtCallback = callback;
129  }
130 
131 protected:
132  // Special internal values, applied to DrawListEntry
133  static const uintptr_t DRAWENTRY_STAGECALLBACK = 0x0;
134  static const uintptr_t DRAWENTRY_FADE = 0x1;
135  static const uintptr_t DRAWENTRY_TINT = 0x2;
136 
137  // Called after graphics driver was initialized for use for the first time
138  virtual void OnInit();
139  // Called just before graphics mode is going to be uninitialized and its
140  // resources released
141  virtual void OnUnInit();
142  // Called after new mode was successfully initialized
143  virtual void OnModeSet(const DisplayMode &mode);
144  // Called when the new native size is set
145  virtual void OnSetNativeRes(const GraphicResolution &native_res);
146  // Called before display mode is going to be released
147  virtual void OnModeReleased();
148  // Called when new render frame is set
149  virtual void OnSetRenderFrame(const Rect &dst_rect);
150  // Called when the new filter is set
151  virtual void OnSetFilter();
152 
153  // Try changing vsync setting; fills new current mode in vsync_res,
154  // returns whether the new setting was set successfully.
155  virtual bool SetVsyncImpl(bool vsync, bool &vsync_res) { return false; }
156 
157  // Initialize sprite batch and allocate necessary resources
158  virtual void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) = 0;
159  // Gets the index of a last draw entry (sprite)
160  virtual size_t GetLastDrawEntryIndex() = 0;
161  // Clears sprite lists
162  virtual void ResetAllBatches() = 0;
163 
164  void OnScalingChanged();
165 
166  DisplayMode _mode; // display mode settings
167  Rect _srcRect; // rendering source rect
168  int _srcColorDepth; // rendering source color depth (in bits per pixel)
169  Rect _dstRect; // rendering destination rect
170  Rect _filterRect; // filter scaling destination rect (before final scaling)
171  PlaneScaling _scaling; // native -> render dest coordinate transformation
172 
173  // Capability flags
174  bool _capsVsync = false; // is vsync available
175 
176  // Callbacks
177  GFXDRV_CLIENTCALLBACK _pollingCallback;
178  GFXDRV_CLIENTCALLBACK _drawScreenCallback;
179  GFXDRV_CLIENTCALLBACK _drawPostScreenCallback;
180  GFXDRV_CLIENTCALLBACKEVT _spriteEvtCallback;
181  GFXDRV_CLIENTCALLBACKINITGFX _initGfxCallback;
182 
183  // Sprite batch parameters
184  SpriteBatchDescs _spriteBatchDesc;
185  // The range of sprites in this sprite batch (counting nested sprites):
186  // the index of a first of the current batch, and the next index past the last one.
187  std::vector<std::pair<size_t, size_t>> _spriteBatchRange;
188  // The index of a currently filled sprite batch
189  size_t _actSpriteBatch;
190  // The index of a currently rendered sprite batch
191  // (or -1 / UINT32_MAX if we are outside of the render pass)
192  uint32_t _rendSpriteBatch;
193 };
194 
195 
196 
197 
198 // Parent class for the video memory DDBs
200 public:
201  int GetWidth() const override {
202  return _width;
203  }
204  int GetHeight() const override {
205  return _height;
206  }
207  int GetColorDepth() const override {
208  return _colDepth;
209  }
210  bool MatchesFormat(AGS::Shared::Bitmap *other) const {
211  return _width == other->GetWidth() && _height == other->GetHeight() && _colDepth == other->GetColorDepth();
212  }
213 
214  int _width = 0, _height = 0;
215  int _colDepth = 0;
216  bool _hasAlpha = false; // has meaningful alpha channel
217  bool _opaque = false; // no mask color
218 
219 protected:
220  BaseDDB() {}
221  virtual ~BaseDDB() {}
222 };
223 
224 // A base parent for the otherwise opaque texture data object;
225 // TextureData refers to the pixel data itself, with no additional
226 // properties. It may be shared between multiple sprites if necessary.
227 struct TextureData {
228  uint32_t ID = UINT32_MAX;
229  bool RenderTarget = false; // replace with flags later
230  virtual ~TextureData() = default;
231 protected:
232  TextureData() = default;
233 };
234 
235 // Generic TextureTile base
236 struct TextureTile {
237  int x = 0, y = 0;
238  int width = 0, height = 0;
239  // allocWidth and allocHeight tell the actual allocated texture size
240  int allocWidth = 0, allocHeight = 0;
241 };
242 
243 
244 // VideoMemoryGraphicsDriver - is the parent class for the graphic drivers
245 // which drawing method is based on passing the sprite stack into GPU,
246 // rather than blitting to flat screen bitmap.
248 public:
250  ~VideoMemoryGraphicsDriver() override;
251 
252  bool RequiresFullRedrawEachFrame() override { return true; }
253  bool HasAcceleratedTransform() override { return true; }
254  // NOTE: although we do use ours, we do not let engine draw upon it;
255  // only plugin handling are allowed to request our mem buffer
256  // for compatibility reasons.
257  bool UsesMemoryBackBuffer() override { return false; }
258 
259  Bitmap *GetMemoryBackBuffer() override;
260  void SetMemoryBackBuffer(Bitmap *backBuffer) override;
261  Bitmap *GetStageBackBuffer(bool mark_dirty) override;
262  void SetStageBackBuffer(Bitmap *backBuffer) override;
263  bool GetStageMatrixes(RenderMatrixes &rm) override;
264  // Creates new texture using given parameters
265  IDriverDependantBitmap *CreateDDB(int width, int height, int color_depth, bool opaque) override = 0;
266  // Creates new texture and copy bitmap contents over
267  IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool has_alpha, bool opaque = false) override;
268  // Get shared texture from cache, or create from bitmap and assign ID
269  IDriverDependantBitmap *GetSharedDDB(uint32_t sprite_id, Bitmap *bitmap, bool has_alpha, bool opaque) override;
270  // Removes the shared texture reference, will force the texture to recreate next time
271  void ClearSharedDDB(uint32_t sprite_id) override;
272  // Updates shared texture data, but only if it is present in the cache
273  void UpdateSharedDDB(uint32_t sprite_id, Bitmap *bitmap, bool has_alpha, bool opaque) override;
274  void DestroyDDB(IDriverDependantBitmap* ddb) override;
275 
276  // Sets stage screen parameters for the current batch.
277  void SetStageScreen(const Size &sz, int x = 0, int y = 0) override;
278 
279 protected:
280  // Create texture data with the given parameters
281  virtual TextureData *CreateTextureData(int width, int height, bool opaque, bool as_render_target = false) = 0;
282  // Update texture data from the given bitmap
283  virtual void UpdateTextureData(TextureData *txdata, Bitmap *bmp, bool has_alpha, bool opaque) = 0;
284  // Create DDB using preexisting texture data
285  virtual IDriverDependantBitmap *CreateDDB(std::shared_ptr<TextureData> txdata,
286  int width, int height, int color_depth, bool opaque) = 0;
287  // Retrieve shared texture data object from the given DDB
288  virtual std::shared_ptr<TextureData> GetTextureData(IDriverDependantBitmap *ddb) = 0;
289  virtual void DestroyDDBImpl(IDriverDependantBitmap* ddb) = 0;
290 
291  // Stage screens are raw bitmap buffers meant to be sent to plugins on demand
292  // at certain drawing stages. If used at least once these buffers are then
293  // rendered as additional sprites in their respected order.
294  // Presets a stage screen with the given position (size is obligatory, offsets not).
295  void SetStageScreen(size_t index, const Size &sz, int x = 0, int y = 0);
296  // Returns a raw bitmap for the given stage screen.
297  Bitmap *GetStageScreenRaw(size_t index);
298  // Updates and returns a DDB for the given stage screen, and optional x,y position;
299  // clears the raw bitmap after copying to the texture.
300  IDriverDependantBitmap *UpdateStageScreenDDB(size_t index, int &x, int &y);
301  // Disposes all the stage screen raw bitmaps and DDBs.
302  void DestroyAllStageScreens();
303  // Use engine callback to pass a render event;
304  // returns a DDB if anything was drawn onto the current stage screen
305  // (in which case it also fills optional x,y position),
306  // or nullptr if this entry should be skipped.
307  IDriverDependantBitmap *DoSpriteEvtCallback(int evt, int data, int &x, int &y);
308 
309  // Prepare and get fx item from the pool
310  IDriverDependantBitmap *MakeFx(int r, int g, int b);
311  // Resets fx pool counter
312  void ResetFxPool();
313  // Disposes all items in the fx pool
314  void DestroyFxPool();
315 
316  // Prepares bitmap to be applied to the texture, copies pixels to the provided buffer
317  void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
318  uint8_t *dst_ptr, const int dst_pitch, const bool usingLinearFiltering);
319  // Same but optimized for opaque source bitmaps which ignore transparent "mask color"
320  void BitmapToVideoMemOpaque(const Bitmap *bitmap, const TextureTile *tile,
321  uint8_t *dst_ptr, const int dst_pitch);
322 
323  // Stage virtual screen is used to let plugins draw custom graphics
324  // in between render stages (between room and GUI, after GUI, and so on)
325  PBitmap _stageVirtualScreen;
326  IDriverDependantBitmap *_stageVirtualScreenDDB;
327  // Stage matrixes are used to let plugins with hardware acceleration know model matrix;
328  // these matrixes are filled compatible with each given renderer
329  RenderMatrixes _stageMatrixes;
330 
331  // Color component shifts in video bitmap format (set by implementations)
332  int _vmem_a_shift_32;
333  int _vmem_r_shift_32;
334  int _vmem_g_shift_32;
335  int _vmem_b_shift_32;
336 
337 private:
338  // Stage virtual screens are used to let plugins draw custom graphics
339  // in between render stages (between room and GUI, after GUI, and so on).
340  // TODO: possibly may be optimized further by having only 1 bitmap/ddb
341  // pair, and subbitmaps for raw drawing on separate stages.
342  struct StageScreen {
343  Rect Position; // bitmap size and pos preset (bitmap may be created later)
345  IDriverDependantBitmap *DDB = nullptr;
346  };
347  std::vector<StageScreen> _stageScreens;
348  // Flag which indicates whether stage screen was drawn upon during engine
349  // callback and has to be inserted into sprite stack.
350  bool _stageScreenDirty;
351 
352  // Fx quads pool (for screen overlay effects)
353  struct ScreenFx {
354  Bitmap *Raw = nullptr;
355  IDriverDependantBitmap *DDB = nullptr;
356  int Red = -1;
357  int Green = -1;
358  int Blue = -1;
359  };
360  std::vector<ScreenFx> _fxPool;
361  size_t _fxIndex; // next free pool item
362 
363  // specialized method to convert bitmap to video memory depending on bit depth
364  template<typename T, bool HasAlpha>
365  void BitmapToVideoMemImpl(const Bitmap *bitmap, const TextureTile *tile, uint8_t *dst_ptr, const int dst_pitch);
366 
367  template<typename T>
368  void BitmapToVideoMemOpaqueImpl(const Bitmap *bitmap, const TextureTile *tile, uint8_t *dst_ptr, const int dst_pitch);
369 
370  template<typename T, bool HasAlpha>
371  void BitmapToVideoMemLinearImpl(const Bitmap *bitmap, const TextureTile *tile, uint8_t *dst_ptr, const int dst_pitch);
372 
373  // Texture short-term cache:
374  // - caches textures while they are in the immediate use;
375  // - this lets to share same texture data among multiple sprites on screen.
376  // TextureCacheItem stores weak references to the existing texture tiles,
377  // identified by an arbitrary uint32 number.
378  // TODO: a curious topic to consider: reuse released TextureData for
379  // textures of the same size (research potential performance impact).
380  struct TextureCacheItem {
381  GraphicResolution Res;
383  TextureCacheItem() = default;
384  TextureCacheItem(std::shared_ptr<TextureData> data, const GraphicResolution &res)
385  : Data(data), Res(res) {}
386  };
388 };
389 
390 } // namespace Engine
391 } // namespace AGS
392 } // namespace AGS3
393 
394 #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:247
Definition: gfx_driver_base.h:199
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:219
Definition: geometry.h:148
Definition: gfx_defines.h:33
Definition: gfx_driver_base.h:227
Definition: gfx_driver_base.h:97
Definition: gfx_driver_base.h:236
Definition: ptr.h:159
Definition: engine.h:144
Definition: graphics_driver.h:85
Definition: ags.h:40
Definition: gfx_driver_base.h:78