2 * Copyright 2006-2009, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
12 #include <BitmapPrivate.h>
14 #include "HWInterface.h"
15 #include "ServerBitmap.h"
18 //#define TRACE_OVERLAY
20 # define TRACE(x...) ktrace_printf(x);
22 # define TRACE(x...) ;
26 const static bigtime_t kOverlayTimeout
= 1000000LL;
27 // after 1 second, the team holding the lock will be killed
29 class SemaphoreLocker
{
31 SemaphoreLocker(sem_id semaphore
, bigtime_t timeout
= B_INFINITE_TIMEOUT
)
36 fStatus
= acquire_sem_etc(fSemaphore
, 1, B_RELATIVE_TIMEOUT
,
38 } while (fStatus
== B_INTERRUPTED
);
44 release_sem_etc(fSemaphore
, 1, B_DO_NOT_RESCHEDULE
);
61 Overlay::Overlay(HWInterface
& interface
, ServerBitmap
* bitmap
,
64 fHWInterface(interface
),
69 fSemaphore
= create_sem(1, "overlay lock");
70 fColor
= (rgb_color
){ 0, 80, 0, 0 };
71 // TODO: whatever fine color we want to use here...
73 fWindow
.offset_top
= 0;
74 fWindow
.offset_left
= 0;
75 fWindow
.offset_right
= 0;
76 fWindow
.offset_bottom
= 0;
78 fWindow
.flags
= B_OVERLAY_COLOR_KEY
;
80 _AllocateBuffer(bitmap
);
82 TRACE("overlay: created %p, bitmap %p\n", this, bitmap
);
88 fHWInterface
.ReleaseOverlayChannel(fOverlayToken
);
91 delete_sem(fSemaphore
);
92 TRACE("overlay: deleted %p\n", this);
97 Overlay::InitCheck() const
99 if (fSemaphore
< B_OK
)
102 if (fOverlayBuffer
== NULL
)
110 Overlay::Resume(ServerBitmap
* bitmap
)
112 SemaphoreLocker
locker(fSemaphore
, kOverlayTimeout
);
113 if (locker
.LockStatus() == B_TIMED_OUT
) {
117 TRACE("overlay: resume %p (lock status %ld)\n", this, locker
.LockStatus());
119 status_t status
= _AllocateBuffer(bitmap
);
123 fClientData
->buffer
= (uint8
*)fOverlayBuffer
->buffer
;
129 Overlay::Suspend(ServerBitmap
* bitmap
, bool needTemporary
)
131 SemaphoreLocker
locker(fSemaphore
, kOverlayTimeout
);
132 if (locker
.LockStatus() == B_TIMED_OUT
) {
136 TRACE("overlay: suspend %p (lock status %ld)\n", this, locker
.LockStatus());
139 fClientData
->buffer
= NULL
;
146 Overlay::_FreeBuffer()
148 fHWInterface
.FreeOverlayBuffer(fOverlayBuffer
);
149 fOverlayBuffer
= NULL
;
154 Overlay::_AllocateBuffer(ServerBitmap
* bitmap
)
156 fOverlayBuffer
= fHWInterface
.AllocateOverlayBuffer(bitmap
->Width(),
157 bitmap
->Height(), bitmap
->ColorSpace());
158 if (fOverlayBuffer
== NULL
)
166 Overlay::SetClientData(overlay_client_data
* clientData
)
168 fClientData
= clientData
;
169 fClientData
->lock
= fSemaphore
;
170 fClientData
->buffer
= (uint8
*)fOverlayBuffer
->buffer
;
175 Overlay::SetFlags(uint32 flags
)
177 if (flags
& B_OVERLAY_FILTER_HORIZONTAL
)
178 fWindow
.flags
|= B_OVERLAY_HORIZONTAL_FILTERING
;
179 if (flags
& B_OVERLAY_FILTER_VERTICAL
)
180 fWindow
.flags
|= B_OVERLAY_VERTICAL_FILTERING
;
181 if (flags
& B_OVERLAY_MIRROR
)
182 fWindow
.flags
|= B_OVERLAY_HORIZONTAL_MIRRORING
;
187 Overlay::TakeOverToken(Overlay
* other
)
189 overlay_token token
= other
->OverlayToken();
193 fOverlayToken
= token
;
194 //other->fOverlayToken = NULL;
198 const overlay_buffer
*
199 Overlay::OverlayBuffer() const
201 return fOverlayBuffer
;
206 Overlay::ClientData() const
213 Overlay::OverlayToken() const
215 return fOverlayToken
;
222 if (fOverlayToken
== NULL
)
225 fHWInterface
.HideOverlay(this);
226 TRACE("overlay: hide %p\n", this);
231 Overlay::SetColorSpace(uint32 colorSpace
)
233 if ((fWindow
.flags
& B_OVERLAY_COLOR_KEY
) == 0)
236 uint8 colorShift
= 0, greenShift
= 0, alphaShift
= 0;
237 rgb_color colorKey
= fColor
;
239 switch (colorSpace
) {
241 greenShift
= colorShift
= 3;
251 fWindow
.red
.value
= colorKey
.red
>> colorShift
;
252 fWindow
.green
.value
= colorKey
.green
>> greenShift
;
253 fWindow
.blue
.value
= colorKey
.blue
>> colorShift
;
254 fWindow
.alpha
.value
= colorKey
.alpha
>> alphaShift
;
255 fWindow
.red
.mask
= 0xff >> colorShift
;
256 fWindow
.green
.mask
= 0xff >> greenShift
;
257 fWindow
.blue
.mask
= 0xff >> colorShift
;
258 fWindow
.alpha
.mask
= 0xff >> alphaShift
;
263 Overlay::Configure(const BRect
& source
, const BRect
& destination
)
265 if (fOverlayToken
== NULL
) {
266 fOverlayToken
= fHWInterface
.AcquireOverlayChannel();
267 if (fOverlayToken
== NULL
)
271 TRACE("overlay: configure %p\n", this);
273 fView
.h_start
= (uint16
)source
.left
;
274 fView
.v_start
= (uint16
)source
.top
;
275 fView
.width
= (uint16
)source
.IntegerWidth() + 1;
276 fView
.height
= (uint16
)source
.IntegerHeight() + 1;
278 fWindow
.h_start
= (int16
)destination
.left
;
279 fWindow
.v_start
= (int16
)destination
.top
;
280 fWindow
.width
= (uint16
)destination
.IntegerWidth() + 1;
281 fWindow
.height
= (uint16
)destination
.IntegerHeight() + 1;
283 fHWInterface
.ConfigureOverlay(this);