* We now have working video overlay - even though the overlay_token handling
is currently broken, mode switches probably fail or result in sudden death (didn't try) it's good enough for Radeon cards and VLC (might work with others as well). * Implemented follow modes for view bitmaps (wasn't taken into account at all before). * Switched to a darker overlay color for now (dunno what exactly makes a good candidate there, but this one is good enough for now). * Added TODO about a race condition in AS_LAYER_SET_VIEW_BITMAP. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17208 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ef9c8e384d
commit
f7c7883b9f
|
@ -2564,7 +2564,7 @@ ServerApp::FindBitmap(int32 token) const
|
|||
ServerBitmap* bitmap;
|
||||
if (gTokenSpace.GetToken(token, kBitmapToken, (void**)&bitmap) == B_OK)
|
||||
return bitmap;
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -375,8 +375,8 @@ OverlayCookie::OverlayCookie(HWInterface& interface)
|
|||
fOverlayToken(NULL)
|
||||
{
|
||||
fSemaphore = create_sem(1, "overlay lock");
|
||||
fColor.SetColor(255, 0, 255);
|
||||
// that color is just for testing, of course!
|
||||
fColor.SetColor(21, 16, 21, 16);
|
||||
// TODO: whatever fine color we want to use here...
|
||||
}
|
||||
|
||||
|
||||
|
@ -409,6 +409,18 @@ OverlayCookie::SetOverlayData(const overlay_buffer* overlayBuffer,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
OverlayCookie::TakeOverToken(OverlayCookie* other)
|
||||
{
|
||||
overlay_token token = other->OverlayToken();
|
||||
if (token == NULL)
|
||||
return;
|
||||
|
||||
fOverlayToken = token;
|
||||
//other->fOverlayToken = NULL;
|
||||
}
|
||||
|
||||
|
||||
const overlay_buffer*
|
||||
OverlayCookie::OverlayBuffer() const
|
||||
{
|
||||
|
@ -429,3 +441,44 @@ OverlayCookie::OverlayToken() const
|
|||
return fOverlayToken;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OverlayCookie::Show()
|
||||
{
|
||||
// TODO: acquire token!
|
||||
if (fOverlayToken == NULL) {
|
||||
printf("%p: no overlay token\n", this);
|
||||
return;
|
||||
}
|
||||
|
||||
fHWInterface.ShowOverlay(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OverlayCookie::Hide()
|
||||
{
|
||||
// TODO: acquire token!
|
||||
if (fOverlayToken == NULL) {
|
||||
printf("%p: no overlay token\n", this);
|
||||
return;
|
||||
}
|
||||
|
||||
fHWInterface.HideOverlay(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OverlayCookie::SetView(const BRect& source, const BRect& destination)
|
||||
{
|
||||
fSource = source;
|
||||
fDestination = destination;
|
||||
|
||||
if (fOverlayToken == NULL) {
|
||||
printf("%p: no overlay token\n", this);
|
||||
return;
|
||||
}
|
||||
|
||||
fHWInterface.UpdateOverlay(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ class OverlayCookie {
|
|||
|
||||
void SetOverlayData(const overlay_buffer* overlayBuffer,
|
||||
overlay_token token, overlay_client_data* clientData);
|
||||
void TakeOverToken(OverlayCookie* other);
|
||||
|
||||
const overlay_buffer* OverlayBuffer() const;
|
||||
overlay_client_data* ClientData() const;
|
||||
|
@ -161,6 +162,20 @@ class OverlayCookie {
|
|||
const RGBColor& Color() const
|
||||
{ return fColor; }
|
||||
|
||||
void SetVisible(bool visible)
|
||||
{ fVisible = visible; }
|
||||
bool IsVisible() const
|
||||
{ return fVisible; }
|
||||
|
||||
void SetView(const BRect& source, const BRect& destination);
|
||||
const BRect& Source() const
|
||||
{ return fSource; }
|
||||
const BRect& Destination() const
|
||||
{ return fDestination; }
|
||||
|
||||
void Show();
|
||||
void Hide();
|
||||
|
||||
private:
|
||||
HWInterface& fHWInterface;
|
||||
const overlay_buffer* fOverlayBuffer;
|
||||
|
@ -168,6 +183,9 @@ class OverlayCookie {
|
|||
overlay_token fOverlayToken;
|
||||
sem_id fSemaphore;
|
||||
RGBColor fColor;
|
||||
BRect fSource;
|
||||
BRect fDestination;
|
||||
bool fVisible;
|
||||
};
|
||||
|
||||
// ShallowCopy (only for server bitmaps)
|
||||
|
|
|
@ -1501,14 +1501,21 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
|||
link.Read<int32>(&resizingMode);
|
||||
status_t status = link.Read<int32>(&options);
|
||||
|
||||
rgb_color colorKey = {0};
|
||||
|
||||
if (status == B_OK) {
|
||||
ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
|
||||
if (bitmapToken == -1 || bitmap != NULL) {
|
||||
// TODO: this is a race condition: the bitmap could have been
|
||||
// deleted in the mean time!!
|
||||
fCurrentLayer->SetViewBitmap(bitmap, srcRect, dstRect,
|
||||
resizingMode, options);
|
||||
|
||||
BRegion dirty(fCurrentLayer->Bounds());
|
||||
fWindowLayer->InvalidateView(fCurrentLayer, dirty);
|
||||
|
||||
if (bitmap != NULL && bitmap->OverlayCookie() != NULL)
|
||||
colorKey = bitmap->OverlayCookie()->Color().GetColor32();
|
||||
} else
|
||||
status = B_BAD_VALUE;
|
||||
}
|
||||
|
@ -1516,8 +1523,6 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
|||
fLink.StartMessage(status);
|
||||
if (status == B_OK && (options & AS_REQUEST_COLOR_KEY) != 0) {
|
||||
// Attach color key for the overlay bitmap
|
||||
// TODO: get color key from the accelerant
|
||||
rgb_color colorKey = {40, 40, 40, 255};
|
||||
fLink.Attach<rgb_color>(colorKey);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,38 @@
|
|||
using std::nothrow;
|
||||
|
||||
|
||||
void
|
||||
resize_frame(BRect& frame, uint32 resizingMode, int32 x, int32 y)
|
||||
{
|
||||
// follow with left side
|
||||
if ((resizingMode & 0x0F00U) == _VIEW_RIGHT_ << 8)
|
||||
frame.left += x;
|
||||
else if ((resizingMode & 0x0F00U) == _VIEW_CENTER_ << 8)
|
||||
frame.left += x / 2;
|
||||
|
||||
// follow with right side
|
||||
if ((resizingMode & 0x000FU) == _VIEW_RIGHT_)
|
||||
frame.right += x;
|
||||
else if ((resizingMode & 0x000FU) == _VIEW_CENTER_)
|
||||
frame.right += x / 2;
|
||||
|
||||
// follow with top side
|
||||
if ((resizingMode & 0xF000U) == _VIEW_BOTTOM_ << 12)
|
||||
frame.top += y;
|
||||
else if ((resizingMode & 0xF000U) == _VIEW_CENTER_ << 12)
|
||||
frame.top += y / 2;
|
||||
|
||||
// follow with bottom side
|
||||
if ((resizingMode & 0x00F0U) == _VIEW_BOTTOM_ << 4)
|
||||
frame.bottom += y;
|
||||
else if ((resizingMode & 0x00F0U) == _VIEW_CENTER_ << 4)
|
||||
frame.bottom += y / 2;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ViewLayer::ViewLayer(BRect frame, BPoint scrollingOffset, const char* name,
|
||||
int32 token, uint32 resizeMode, uint32 flags)
|
||||
:
|
||||
|
@ -417,8 +449,18 @@ void
|
|||
ViewLayer::SetViewBitmap(ServerBitmap* bitmap, BRect sourceRect,
|
||||
BRect destRect, int32 resizingMode, int32 options)
|
||||
{
|
||||
if (fViewBitmap != NULL)
|
||||
if (fViewBitmap != NULL) {
|
||||
if (bitmap != NULL) {
|
||||
// take over overlay token from current overlay (if it has any)
|
||||
OverlayCookie* oldOverlay = _Overlay();
|
||||
OverlayCookie* newOverlay = bitmap->OverlayCookie();
|
||||
|
||||
if (oldOverlay != NULL && newOverlay != NULL)
|
||||
newOverlay->TakeOverToken(oldOverlay);
|
||||
}
|
||||
|
||||
gBitmapManager->DeleteBitmap(fViewBitmap);
|
||||
}
|
||||
|
||||
// the caller is allowed to delete the bitmap after setting the background
|
||||
if (bitmap != NULL)
|
||||
|
@ -436,6 +478,32 @@ ViewLayer::SetViewBitmap(ServerBitmap* bitmap, BRect sourceRect,
|
|||
roundf(fBitmapDestination.top));
|
||||
fBitmapDestination.right = roundf(fBitmapDestination.right);
|
||||
fBitmapDestination.bottom = roundf(fBitmapDestination.bottom);
|
||||
|
||||
_UpdateOverlayView();
|
||||
}
|
||||
|
||||
|
||||
OverlayCookie*
|
||||
ViewLayer::_Overlay() const
|
||||
{
|
||||
if (fViewBitmap == NULL)
|
||||
return NULL;
|
||||
|
||||
return fViewBitmap->OverlayCookie();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewLayer::_UpdateOverlayView() const
|
||||
{
|
||||
OverlayCookie* overlay = _Overlay();
|
||||
if (overlay == NULL)
|
||||
return;
|
||||
|
||||
BRect destination = fBitmapDestination;
|
||||
ConvertToScreen(&destination);
|
||||
|
||||
overlay->SetView(fBitmapSource, destination);
|
||||
}
|
||||
|
||||
|
||||
|
@ -680,6 +748,9 @@ ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
|
|||
// the screen clipping
|
||||
InvalidateScreenClipping(true);
|
||||
}
|
||||
|
||||
// overlay handling
|
||||
_UpdateOverlayView();
|
||||
}
|
||||
|
||||
// ResizeBy
|
||||
|
@ -734,43 +805,26 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
|
|||
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling())
|
||||
child->ParentResized(x, y, dirtyRegion);
|
||||
|
||||
// view bitmap
|
||||
|
||||
resize_frame(fBitmapDestination, fBitmapResizingMode, x, y);
|
||||
|
||||
// at this point, children are at their new locations,
|
||||
// so we can rebuild the clipping
|
||||
// TODO: when the implementation of Hide() and Show() is
|
||||
// complete, see if this should be avoided
|
||||
RebuildClipping(false);
|
||||
|
||||
// overlay handling
|
||||
_UpdateOverlayView();
|
||||
}
|
||||
|
||||
// ParentResized
|
||||
void
|
||||
ViewLayer::ParentResized(int32 x, int32 y, BRegion* dirtyRegion)
|
||||
{
|
||||
uint16 rm = fResizeMode & 0x0000FFFF;
|
||||
BRect newFrame = fFrame;
|
||||
|
||||
// follow with left side
|
||||
if ((rm & 0x0F00U) == _VIEW_RIGHT_ << 8)
|
||||
newFrame.left += x;
|
||||
else if ((rm & 0x0F00U) == _VIEW_CENTER_ << 8)
|
||||
newFrame.left += x / 2;
|
||||
|
||||
// follow with right side
|
||||
if ((rm & 0x000FU) == _VIEW_RIGHT_)
|
||||
newFrame.right += x;
|
||||
else if ((rm & 0x000FU) == _VIEW_CENTER_)
|
||||
newFrame.right += x / 2;
|
||||
|
||||
// follow with top side
|
||||
if ((rm & 0xF000U) == _VIEW_BOTTOM_ << 12)
|
||||
newFrame.top += y;
|
||||
else if ((rm & 0xF000U) == _VIEW_CENTER_ << 12)
|
||||
newFrame.top += y / 2;
|
||||
|
||||
// follow with bottom side
|
||||
if ((rm & 0x00F0U) == _VIEW_BOTTOM_ << 4)
|
||||
newFrame.bottom += y;
|
||||
else if ((rm & 0x00F0U) == _VIEW_CENTER_ << 4)
|
||||
newFrame.bottom += y / 2;
|
||||
resize_frame(newFrame, fResizeMode & 0x0000ffff, x, y);
|
||||
|
||||
if (newFrame != fFrame) {
|
||||
// careful, MoveBy will change fFrame
|
||||
|
@ -978,9 +1032,7 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
|
|||
// add the current clipping
|
||||
redraw->IntersectWith(effectiveClipping);
|
||||
|
||||
OverlayCookie* overlayCookie = NULL;
|
||||
if (fViewBitmap != NULL)
|
||||
overlayCookie = fViewBitmap->OverlayCookie();
|
||||
OverlayCookie* overlayCookie = _Overlay();
|
||||
|
||||
if (fViewBitmap != NULL && overlayCookie == NULL) {
|
||||
// draw view bitmap
|
||||
|
@ -1064,14 +1116,13 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
|
|||
|
||||
}
|
||||
|
||||
if (overlayCookie != NULL) {
|
||||
drawingEngine->FillRegion(*redraw, overlayCookie->Color());
|
||||
} else if (!fViewColor.IsTransparentMagic()) {
|
||||
if (!fViewColor.IsTransparentMagic()) {
|
||||
// fill visible region with view color,
|
||||
// this version of FillRegion ignores any
|
||||
// clipping, that's why "redraw" needs to
|
||||
// be correct
|
||||
drawingEngine->FillRegion(*redraw, fViewColor);
|
||||
drawingEngine->FillRegion(*redraw, overlayCookie != NULL
|
||||
? overlayCookie->Color() : fViewColor);
|
||||
}
|
||||
|
||||
fWindow->RecycleRegion(redraw);
|
||||
|
@ -1160,6 +1211,17 @@ ViewLayer::UpdateVisibleDeep(bool parentVisible)
|
|||
fVisible = parentVisible && !fHidden;
|
||||
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling())
|
||||
child->UpdateVisibleDeep(fVisible);
|
||||
|
||||
// overlay handling
|
||||
|
||||
OverlayCookie* overlay = _Overlay();
|
||||
if (overlay == NULL)
|
||||
return;
|
||||
|
||||
if (fVisible && !overlay->IsVisible())
|
||||
overlay->Show();
|
||||
else if (!fVisible && overlay->IsVisible())
|
||||
overlay->Hide();
|
||||
}
|
||||
|
||||
// MarkBackgroundDirty
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace BPrivate {
|
|||
|
||||
class DrawState;
|
||||
class DrawingEngine;
|
||||
class OverlayCookie;
|
||||
class WindowLayer;
|
||||
class ServerBitmap;
|
||||
class ServerCursor;
|
||||
|
@ -208,6 +209,8 @@ class ViewLayer {
|
|||
protected:
|
||||
void _MoveScreenClipping(int32 x, int32 y,
|
||||
bool deep);
|
||||
OverlayCookie* _Overlay() const;
|
||||
void _UpdateOverlayView() const;
|
||||
|
||||
BString fName;
|
||||
int32 fToken;
|
||||
|
|
|
@ -761,6 +761,57 @@ AccelerantHWInterface::FreeOverlayBuffer(const overlay_buffer* buffer)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
AccelerantHWInterface::ShowOverlay(OverlayCookie* overlay)
|
||||
{
|
||||
UpdateOverlay(overlay);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccelerantHWInterface::HideOverlay(OverlayCookie* overlay)
|
||||
{
|
||||
fAccConfigureOverlay(overlay->OverlayToken(), overlay->OverlayBuffer(), NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccelerantHWInterface::UpdateOverlay(OverlayCookie* overlay)
|
||||
{
|
||||
const overlay_buffer* buffer = overlay->OverlayBuffer();
|
||||
|
||||
overlay_view view;
|
||||
view.h_start = (uint16)overlay->Source().left;
|
||||
view.v_start = (uint16)overlay->Source().top;
|
||||
view.width = (uint16)overlay->Source().IntegerWidth() + 1;
|
||||
view.height = (uint16)overlay->Source().IntegerHeight() + 1;
|
||||
|
||||
overlay_window window;
|
||||
window.h_start = (int16)overlay->Destination().left;
|
||||
window.v_start = (int16)overlay->Destination().top;
|
||||
window.width = (uint16)overlay->Destination().IntegerWidth() + 1;
|
||||
window.height = (uint16)overlay->Destination().IntegerHeight() + 1;
|
||||
|
||||
window.offset_top = 0;
|
||||
window.offset_left = 0;
|
||||
window.offset_right = 0;
|
||||
window.offset_bottom = 0;
|
||||
|
||||
// TODO: for now, this should be done somewhere else, ideally
|
||||
rgb_color colorKey = overlay->Color().GetColor32();
|
||||
window.red.value = colorKey.red;
|
||||
window.green.value = colorKey.green;
|
||||
window.blue.value = colorKey.blue;
|
||||
window.alpha.value = colorKey.alpha;
|
||||
window.red.mask = 0xff;
|
||||
window.green.mask = 0xff;
|
||||
window.blue.mask = 0xff;
|
||||
window.alpha.mask = 0xff;
|
||||
|
||||
fAccConfigureOverlay(overlay->OverlayToken(), buffer, &window, &view);
|
||||
}
|
||||
|
||||
|
||||
// CopyRegion
|
||||
void
|
||||
AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList,
|
||||
|
|
|
@ -65,6 +65,10 @@ public:
|
|||
color_space space);
|
||||
virtual void FreeOverlayBuffer(const overlay_buffer* buffer);
|
||||
|
||||
virtual void ShowOverlay(OverlayCookie* overlay);
|
||||
virtual void HideOverlay(OverlayCookie* overlay);
|
||||
virtual void UpdateOverlay(OverlayCookie* overlay);
|
||||
|
||||
// accelerated drawing
|
||||
virtual void CopyRegion(const clipping_rect* sortedRectList,
|
||||
uint32 count,
|
||||
|
|
|
@ -335,6 +335,24 @@ HWInterface::FreeOverlayBuffer(const overlay_buffer* buffer)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
HWInterface::ShowOverlay(OverlayCookie* overlay)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HWInterface::HideOverlay(OverlayCookie* overlay)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HWInterface::UpdateOverlay(OverlayCookie* overlay)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// HideSoftwareCursor
|
||||
bool
|
||||
HWInterface::HideSoftwareCursor(const BRect& area)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <Region.h>
|
||||
|
||||
|
||||
class OverlayCookie;
|
||||
class RenderingBuffer;
|
||||
class RGBColor;
|
||||
class ServerBitmap;
|
||||
|
@ -106,6 +107,10 @@ class HWInterface : public MultiLocker {
|
|||
color_space space);
|
||||
virtual void FreeOverlayBuffer(const overlay_buffer* buffer);
|
||||
|
||||
virtual void ShowOverlay(OverlayCookie* overlay);
|
||||
virtual void HideOverlay(OverlayCookie* overlay);
|
||||
virtual void UpdateOverlay(OverlayCookie* overlay);
|
||||
|
||||
// frame buffer access (you need to ReadLock!)
|
||||
RenderingBuffer* DrawingBuffer() const;
|
||||
virtual RenderingBuffer* FrontBuffer() const = 0;
|
||||
|
|
Loading…
Reference in New Issue