OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
memorydc.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1992, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of TMemoryDC and TDibDC encapsulation classes
7//----------------------------------------------------------------------------
8#include <owl/pch.h>
9#include <owl/dc.h>
10#include <owl/gdiobjec.h>
11
12#if defined(BI_MULTI_THREAD_RTL)
13#include <owl/thread.h>
14#endif
15
16#if defined(__BORLANDC__)
17# pragma option -w-ccc // Disable "Condition is always true/false"
18#endif
19
20using namespace std;
21
22namespace owl {
23
25DIAG_DECLARE_GROUP(OwlGDI); // General GDI diagnostic group
26
27//
28// class TMemDCCache
29// ~~~~~ ~~~~~~~~~~~
30// Cache of screen-compatible memory HDCs used automatically by TMemoryDC when
31// the default ctor is called. Reduces the amount of HDC creations & allows
32// centralized sharing of these memory HDCs. The cache grows on demand.
33//
34class TMemDCCache
36 : public TLocalObject
37#endif
38{
39 public:
40 enum {MaxEntries = 16}; // Max # of mem DCs allowed in the cache
41
42 struct TEntry {
43 HDC Handle;
44 bool Busy;
45 };
46
47 TMemDCCache();
48 ~TMemDCCache();
49 HDC Get();
50 void Release(HDC hDC);
51
52#if defined(BI_MULTI_THREAD_RTL)
53// TMRSWSection Lock;
54#endif
55
56 private:
57 TEntry Entries[MaxEntries];
58};
59
60//
61// Static instance of the TMemoryDC cache used by TMemoryDC
62//
63static TMemDCCache& GetMemDCCache()
64{
65#if defined(BI_MULTI_THREAD_RTL)
67 return memDCCache.Get();
68#else
69 static TMemDCCache memDCCache;
70 return memDCCache;
71#endif
72};
73
74namespace
75{
76 //
77 // Ensure singleton initialization at start-up (single-threaded, safe).
78 //
79 TMemDCCache& InitMemDCCache = GetMemDCCache();
80}
81
82#if defined(BI_MULTI_THREAD_RTL)
83#define LOCKCACHE //TMRSWSection::TLock Lock(GetMemDCCache().Lock);
84#else
85#define LOCKCACHE
86#endif
87
88//
89//
90//
91TMemDCCache::TMemDCCache()
92{
94 for (int i = 0; i < MaxEntries; i++) {
95 Entries[i].Handle = nullptr;
96 Entries[i].Busy = false;
97 }
98}
99
100//
101//
102//
103TMemDCCache::~TMemDCCache()
104{
106 for (int i = 0; i < MaxEntries && Entries[i].Handle; i++) {
107 WARNX(OwlGDI, Entries[i].Busy, 0, _T("Unreleased DC ") <<
108 static_cast<void*>(Entries[i].Handle) << _T(" in MemDCCache at destruction"));
109 ::DeleteDC(Entries[i].Handle);
110 }
111}
112
113//
114// Get a screen compatible memory HDC from the cache, creating one if needed
115// and there is room.
116//
117HDC
118TMemDCCache::Get()
119{
121 for (int i = 0; i < MaxEntries; i++) {
122 if (!Entries[i].Handle) {
123 // Use a screen dc as reference when constructing the compatible DC
124 // since in some rare situations CreateCompatibleDC(0) fails.
125 //
126 HDC sdc = ::GetWindowDC(nullptr);
127 Entries[i].Handle = ::CreateCompatibleDC(sdc);
128 ::ReleaseDC(nullptr, sdc);
129 }
130 if (!Entries[i].Busy) {
131 Entries[i].Busy = true;
132 return Entries[i].Handle;
133 }
134 }
135 return nullptr; // Cache is full
136}
137
138//
139//
140//
141void
142TMemDCCache::Release(HDC hDC)
143{
145 for (int i = 0; i < MaxEntries && Entries[i].Handle; i++) {
146 if (Entries[i].Handle == hDC) {
147 WARNX(OwlGDI, !Entries[i].Busy, 0, "Releasing non-busy DC " <<
148 static_cast<void*>(Entries[i].Handle) << " in MemDCCache");
149 Entries[i].Busy = false;
150 return;
151 }
152 }
153}
154
155//////////////////////////////////////////////////////////////////////////////////////////////////
156
157//
158/// Constructs a screen-compatible memory DC.
159//
161:
162 TCreatedDC()
163{
164 Init();
165}
166
167//
168/// Constructs a memory DC compatible with a non-screen DC.
169//
171:
172 TCreatedDC()
173{
175 CheckValid();
176}
177
178//
179/// Constructs a TDC using an existing HDC.
180/// If `autoDelete` is `true`, the handle is owned and deleted on destruction.
181//
187
188//
189/// Constructs a screen-compatible memory DC, with the given bitmap selected into it.
190//
192:
193 TCreatedDC()
194{
195 Init();
197}
198
199//
200/// A protected pass-thru constructor for use by derived classes.
201//
205
206//
207/// String-aware overload
208//
212
213#if defined(OWL5_COMPAT)
214
215//
216/// A protected pass-thru constructor for use by derived classes.
217//
220:
222{
223}
224
225//
226/// A protected pass-thru constructor for use by derived classes.
227//
229:
230 TCreatedDC(driver, device, output, initData)
231{
232}
233
234#endif
235
236//
237// Initialization for screen compatible DC construction.
238// Tries to allocate a handle in the internal memory DC cache. If that fails (cache full), then
239// we create our own.
240//
241void
242TMemoryDC::Init()
243{
244 Handle = GetMemDCCache().Get();
245 if (Handle) {
246 ShouldDelete = false; // Found, let the cache own the handle
247 }
248 else {
249 Handle = ::CreateCompatibleDC(nullptr); // Cache is full, we own the handle
250 CheckValid();
251 }
252}
253
254//
255// Releases our handle if it has been allocated from the internal memory DC cache.
256//
258{
259 if (!ShouldDelete) // The HDC is never from the cache if ShouldDelete
260 GetMemDCCache().Release(GetHDC());
261}
262
263} // OWL namespace
264/* ========================================================================== */
265
#define LOCKCACHE(l, s)
Definition brush.cpp:92
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
TBitmap is the GDI bitmap class derived from TGdiObject.
Definition gdiobjec.h:510
An abstract TDC class, TCreatedDC serves as the base for DCs that are created and deleted.
Definition dc.h:724
TDC is the root class for GDI DC wrappers.
Definition dc.h:64
void SelectObject(const TBrush &brush)
Selects the given GDI brush object into this DC.
Definition dc.cpp:113
void CheckValid(uint resId=IDS_GDIFAILURE)
Definition gdibase.cpp:49
bool ShouldDelete
< The handle of this DC. Uses the base class's handle (TGdiBase::Handle.)
Definition gdibase.h:82
HANDLE Handle
< make this function available to derivatives
Definition gdibase.h:81
HDC GetHDC() const
Return the handle of the device context.
Definition dc.h:981
TMemoryDC()
Constructs a screen-compatible memory DC.
Definition memorydc.cpp:160
#define _T(x)
Definition cygwin.h:51
Definition of GDI DC encapsulation classes: TDC, TWindowDC, TScreenDC, TDesktopDC,...
Definition of abstract GDI object class and derived classes.
TAutoDelete
Flag for Handle ctors to control Handle deletion in dtor.
Definition gdibase.h:70
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
OWL_DIAGINFO
Definition animctrl.cpp:14
std::string tstring
Definition defs.h:79