]> git.vomp.tv Git - vompclient.git/blob - osdvector.h
Revert ref-count-negative commit
[vompclient.git] / osdvector.h
1 /*
2     Copyright 2004-2005 Chris Tallon, 2006,2011-2012 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #ifndef OSDVECTOR_H
21 #define OSDVECTOR_H
22
23 #include <set>
24 #include <list>
25 #include <vector>
26 #include <map>
27 #include <queue>
28 #include <string>
29 #include <mutex>
30 #include <thread>
31 #include <condition_variable>
32
33 #include "defines.h"
34 #include "messagequeue.h"
35 #include "osd.h"
36 #include "colour.h"
37 #include "tvmedia.h"
38 #include "vdr.h"
39 #include "teletextdecodervbiebu.h"
40
41 class LogNT;
42
43 enum SVGCommandInstr
44 {
45   DrawNoop,
46   DrawPath,
47   DrawGlyph,
48   DrawImage,
49   DrawTTchar,
50   DrawClipping,
51   DrawImageLoading
52 };
53
54 enum PathIndex
55 {
56   PIHorzLine,
57   PIVertLine,
58   PIRectangle,
59   PIPoint
60 };
61
62 enum Corner
63 {
64   TopLeft,
65   TopRight,
66   BottomLeft,
67   BottomRight,
68   TopMiddle,
69   BottomMiddle,
70   TopLeftLimited
71 };
72
73 typedef VectorHandle VectorHandleImage;
74 typedef unsigned long long LoadingIndex;
75
76 class SVGCommand
77 {
78   public:
79     inline static SVGCommand PaintPath(float ix, float iy, float iw, float ih, PathIndex path, VectorHandle ref)
80     {
81       SVGCommand nc;
82       nc.instr = DrawPath;
83       nc.x = ix;
84       nc.y = iy;
85       nc.w = iw;
86       nc.h = ih;
87       nc.target.path_index = path;
88       nc.handle = ref; // always a valid DrawStyle handle
89       return nc;
90     };
91
92     inline static SVGCommand PaintImageLoading(LoadingIndex load_in, float ix, float iy, float iw, float ih, Corner corner = TopLeft)
93     {
94       SVGCommand nc;
95       nc.instr = DrawImageLoading;
96       nc.x = ix;
97       nc.y = iy;
98       nc.w = iw;
99       nc.h = ih;
100       nc.target.loadindex = load_in;
101       nc.handle = 0; // not valid for PaintImageLoading
102       nc.corner = corner;
103       return nc;
104     };
105
106     inline static SVGCommand PaintImage(float ix, float iy, float iw, float ih, VectorHandleImage handle, VectorHandle ref, Corner corner = TopLeft)
107     {
108       SVGCommand nc;
109       nc.instr = DrawImage;
110       nc.x = ix;
111       nc.y = iy;
112       nc.w = iw;
113       nc.h = ih;
114       nc.target.image = handle;
115       nc.handle = ref; // can be 0 (no handle) or can be an Drawstyle nandle
116       nc.corner = corner;
117       return nc;
118     };
119
120     inline static SVGCommand PaintTTchar(float ix, float iy, float iw, float ih, unsigned int ttchar_in)
121     {
122       SVGCommand nc;
123       nc.instr = DrawTTchar;
124       nc.x = ix;
125       nc.y = iy;
126       nc.w = iw;
127       nc.h = ih;
128       nc.handle = 0; // not valid for PaintTTchar
129       nc.target.ttchar = ttchar_in;
130       nc.corner = TopLeft;
131       return nc;
132     };
133
134     inline static SVGCommand PaintClipping(float ix, float iy, float iw, float ih)
135     {
136       SVGCommand nc;
137       nc.instr = DrawClipping;
138       nc.x = ix;
139       nc.y = iy;
140       nc.w = iw;
141       nc.h = ih;
142       nc.handle = 0; // not valid for PaintClipping
143       nc.target.ttchar = 0;
144       return nc;
145     };
146
147     inline static void PaintGlyph(SVGCommand& nc, float ix, float iy, wchar_t char_in, VectorHandle ref)
148     {
149       nc.instr = DrawGlyph;
150       nc.x = ix;
151       nc.y = iy;
152       nc.w = 0;
153       nc.h = 0;
154       nc.handle = ref; // always a valid DrawStyle handle
155       nc.target.textchar = char_in;
156     };
157
158     bool Test(float tx, float ty, float tw, float th)
159     {
160       return (x >= tx) && (y >= ty) && ((x + w) <= (tx + tw)) && ((y + h) <= (ty + th));
161     }
162
163     bool TTTest(float tox, float toy, float tx, float ty)
164     {
165       return (x == tox) && (toy == y) && (w == tx) && (h == ty);
166     }
167
168     bool Outside(float tx, float ty, float tw, float th)
169     {
170       return ((x + w) < tx) || ((y + h) < ty) || ((tx + tw) < x) || ((ty + th) < y);
171     }
172
173     VectorHandle getHandle()
174     {
175       return handle;
176     };
177
178     VectorHandleImage getImageHandle()
179     {
180       if (instr != DrawImage) return 0;
181       else return target.image;
182     };
183
184     LoadingIndex getLoadingIndex()
185     {
186       if (instr != DrawImageLoading) return 0;
187       else return target.loadindex;
188     };
189
190     SVGCommandInstr instr{DrawNoop};
191     Corner corner;
192     float x{}, y{}, w{}, h{};
193     VectorHandle handle{VECTOR_HANDLE_INIT};
194     union
195     {
196       PathIndex path_index;
197       wchar_t textchar;
198       VectorHandleImage image;
199       unsigned int ttchar;
200       LoadingIndex loadindex;
201     } target;
202 };
203
204 class SurfaceVector;
205 class VDR_ResponsePacket;
206
207 struct SurfaceInfo
208 {
209   const SurfaceVector* surface;
210   std::vector<SVGCommand> commands;
211   float x, y, w, h;
212 };
213
214 class OsdVector : public Osd, public MessageReceiver
215 {
216   public:
217     void dumpImages();
218
219     OsdVector();
220     virtual ~OsdVector();
221
222     int restore();
223
224     bool screenShot(const char* fileName);
225     virtual bool screenShotInternal(void* buffer, int width, int height, bool osd /*include osd*/) = 0;
226
227     Surface* createNewSurface();
228
229     void Blank();
230     virtual void updateBackgroundColor(DrawStyle /* bg */) {};
231
232     void updateOrAddSurface(const SurfaceVector* surf, float x, float y, float height, float width,
233                             std::vector<SVGCommand>& commands);
234     void removeSurface(const SurfaceVector* surf);
235
236     virtual float getFontHeight() = 0;
237     virtual float getCharWidth(wchar_t c) = 0;
238     float* getCharWidthArray() {return byte_char_width;};
239     virtual void getScreenSize(int& width, int& height) = 0;
240     virtual void getRealScreenSize(int& width, int& height) = 0;
241
242     virtual bool getStaticImageData(unsigned int static_id, UCHAR** userdata, ULONG* length) = 0;
243
244     // Used only by OsdVector and SurfaceVector
245     void removeImageRef(const VectorHandleImage ref);
246     void removeLoadingIndexRef(const LoadingIndex ref);
247     VectorHandle getDrawStyleHandle(const DrawStyle& c);
248     void decrementDrawStyleHandleRefCount(VectorHandle ref);
249     LoadingIndex getTVMediaRef(TVMediaInfo& tvmedia, VectorHandleImage& handle);
250     //virtual VectorHandleImage getJpegRef(const char* fileName, int *width,int *height);
251     virtual VectorHandleImage getMonoBitmapRef(void* base, int width, int height);
252     virtual VectorHandleImage getImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data);
253
254
255     // should be only called from control thread
256     void informPicture(LoadingIndex index, VectorHandleImage handle);
257     void processMessage(Message* m);
258
259
260     int charSet() {return 2;}; //UTF-8
261
262
263     class PictureDecoder;
264     struct PictureInfo
265     {
266       enum PictType
267       {
268         RGBAMemBlock,
269         EGLImage,
270         D2DBitmap
271       };
272       PictType type;
273       ULONG width;
274       ULONG height;
275       LoadingIndex lindex;
276       union
277       {
278         const void* image;
279         unsigned int handle;
280       };
281       void* reference;
282       PictureDecoder* decoder;
283     };
284
285
286     class PictureReader;
287
288     class PictureDecoder
289     {
290       public:
291         PictureDecoder(PictureReader* /*treader*/) {/* reader = treader; */};
292         virtual ~PictureDecoder() {};
293
294         // its is always guaranted, that after getDecodedPicture a call to decodePicture follows, if the return value was true;
295         virtual unsigned char* decodePicture(LoadingIndex index, unsigned char* buffer, unsigned int length, bool freemem = true) = 0;
296
297         virtual bool getDecodedPicture(struct PictureInfo& pict_inf) = 0;
298         virtual void freeReference(void* ref) = 0;
299
300         virtual void init() {};
301         virtual void shutdown() {};
302
303       protected:
304         //PictureReader* reader;
305     };
306
307     class PictureReader
308     {
309       public:
310         ~PictureReader();
311         void init();
312         void addDecoder(PictureDecoder*);
313         void removeDecoder(PictureDecoder*);
314         void shutdown();
315         bool processReceivedPictures();
316
317         // should be called from control thread
318         void receivePicture(VDR_ResponsePacket* vresp);
319
320         void addStaticImage(unsigned int id);
321         void invalidateLoadingIndex(LoadingIndex index);
322         void informFallback(LoadingIndex index, int fallback);
323
324       protected:
325
326         void threadMethod();
327         std::mutex threadMutex;
328         std::thread readerThread;
329         bool threadReqQuit{};
330         std::condition_variable threadCond;
331         bool runLoop{};
332
333         std::mutex pict_lock_incoming; //locks
334         std::mutex decoders_lock;
335         std::queue<VDR_ResponsePacket*> pict_incoming;
336         std::queue<unsigned int> pict_incoming_static;
337         std::list<PictureDecoder*> decoders;
338         std::map<LoadingIndex, int> inform_fallback;
339         std::set<LoadingIndex> invalid_loadindex;
340
341         bool picture_update;
342     };
343
344     PictureReader* getPictReader() { return &reader; };
345
346   protected:
347     LogNT* logger{};
348
349     PictureReader reader;
350
351     float byte_char_width[256]{};
352
353
354     virtual void destroyImageRef(VectorHandleImage handle) = 0;
355     //virtual VectorHandleImage createJpeg(const char* fileName, int *width,int *height)=0;
356     virtual VectorHandleImage createMonoBitmap(void* base, int width, int height) = 0;
357     virtual VectorHandleImage createImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data) = 0;
358     virtual void createPicture(struct PictureInfo& pict_inf) = 0;
359     virtual VectorHandle createDrawStyleHandle(const DrawStyle& c) = 0;
360     virtual void destroyDrawStyleHandle(VectorHandle index) = 0;
361     virtual void drawSetTrans(SurfaceInfo& sc) = 0;
362     virtual void executeDrawCommand(SVGCommand& command) = 0;
363
364     void drawSurfaces();
365
366     #if DEV
367     void dumpStyles();
368     #endif
369
370   // See what we can make private in OsdVector
371   private:
372
373     // Methods that only seem to be called internally
374     void incImageRef(VectorHandleImage handle);
375     void incLoadingIndexRef(LoadingIndex index);
376     int getLoadingIndexRef(LoadingIndex index);
377     void decrementAllRefCounts(std::vector<SVGCommand>& commands);
378     void incrementAllRefCounts(std::vector<SVGCommand>& commands);
379     void cleanupOrphanedRefs();
380     void incrementDrawStyleHandleRefCount(VectorHandle index);
381     LoadingIndex loadTVMedia(TVMediaInfo& tvmedia);
382
383     // int getImageRef(VectorHandleImage handle); // Not used anywhere
384
385
386
387     // All the below are data structures only touched by this base class OsdVector
388
389     std::map<TVMediaInfo, VectorHandleImage> tvmedias;
390     std::map<void*, VectorHandleImage> monobitmaps;
391     //map<string,VectorHandleImage> jpegs;
392     std::list<VectorHandleImage> palettepics;
393
394     std::map<VectorHandleImage, int> vhi_refcounts;   // This appears to cover all 3 (4) of the above types
395
396     std::map<LoadingIndex, int> loadindex_ref;
397     std::map<TVMediaInfo, LoadingIndex> tvmedias_load;
398     std::map<LoadingIndex, TVMediaInfo> tvmedias_load_inv;
399     std::map<LoadingIndex, VectorHandleImage> tvmedias_loaded;
400
401
402     std::map<DrawStyle, VectorHandle> drawstyleHandles;
403     std::map<DrawStyle, VectorHandle>::iterator drawstyleHandles_lastit;
404     bool drawstyleHandles_lastit_valid{};
405
406     std::map<VectorHandle, int> drawstyleHandlesRefCounts;
407     std::map<VectorHandle, int>::iterator drawstyleHandlesRefCounts_lastit;
408     bool drawstyleHandlesRefCounts_lastit_valid{};
409
410     std::list<SurfaceInfo> surfaces;
411     using SurfacesIterator = std::list<SurfaceInfo>::iterator;
412     std::mutex surfaces_mutex;
413
414 };
415
416 #endif