added 1 changeset to branch 'refs/remotes/looncraz-github/compositing' old head: fe7207954e1107589c440b9181a85a2a4fcc352f new head: 4dfc535ea074e07a920b504c33f2415509e801b3 ---------------------------------------------------------------------------- 4dfc535: CompositeOverlay server-side comms And supporting features in CompositeEngine & CompositeScreenStates. Not certain blocking updates by region will be the way to go without disabling updates for any window which intersects with the blocked region. Blocking is generallly very quick, and is to be performed when double-buffering is not in place for CompositeOverlays or WindowBuffers (which will be the initial state). [ looncraz <looncraz@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- Commit: 4dfc535ea074e07a920b504c33f2415509e801b3 Author: looncraz <looncraz@xxxxxxxxxxx> Date: Tue Apr 24 20:16:26 2012 UTC ---------------------------------------------------------------------------- 9 files changed, 265 insertions(+), 9 deletions(-) src/kits/interface/CompositeOverlay.cpp | 2 +- src/servers/app/ProfileMessageSupport.cpp | 23 +++- src/servers/app/ProfileMessageSupport.h | 1 + .../app/drawing/compositing/CompositeEngine.cpp | 27 ++++ .../app/drawing/compositing/CompositeEngine.h | 5 + .../app/drawing/compositing/CompositeOverlay.cpp | 123 +++++++++++++++- .../app/drawing/compositing/CompositeOverlay.h | 2 + .../drawing/compositing/CompositeScreenStates.cpp | 73 +++++++++- .../drawing/compositing/CompositeScreenStates.h | 18 ++- ---------------------------------------------------------------------------- diff --git a/src/kits/interface/CompositeOverlay.cpp b/src/kits/interface/CompositeOverlay.cpp index 654a7a0..145ed76 100644 --- a/src/kits/interface/CompositeOverlay.cpp +++ b/src/kits/interface/CompositeOverlay.cpp @@ -508,7 +508,7 @@ BCompositeOverlay::_LinkLoop() if (fLink->Read<bool>(&forceQuit) != B_OK) break; - if (forceQuit){ + if (forceQuit && !fIsQuitting){ int32 maxTries = 10; while (QuitRequested(true) == false && --maxTries > 0) snooze(2000); diff --git a/src/servers/app/ProfileMessageSupport.cpp b/src/servers/app/ProfileMessageSupport.cpp index ad18b6a..c19bcfe 100644 --- a/src/servers/app/ProfileMessageSupport.cpp +++ b/src/servers/app/ProfileMessageSupport.cpp @@ -12,6 +12,14 @@ #include <ServerProtocol.h> +const char* string_for_message_code(uint32 code) +{ + BString string; + string_for_message_code(code, string); + return string.String(); +} + + void string_for_message_code(uint32 code, BString& string) { @@ -94,7 +102,7 @@ string_for_message_code(uint32 code, BString& string) CODE(AS_SET_ALPHA_REGION); CODE(AS_GET_ALPHA_REGION); - // Compositing definitions + // Compositing definitions CODE(AS_COMPOSITE_ENGINE_FIRST); CODE(AS_GET_COMPOSITING_FPS); CODE(AS_GET_COMPOSITING_FPS_AVERAGE); @@ -106,8 +114,21 @@ string_for_message_code(uint32 code, BString& string) CODE(AS_SET_EFFECT_CONFIG); CODE(AS_GET_EFFECT_CONFIG); CODE(AS_REQUEST_EFFECT); + CODE(AS_SET_FPS_OVERLAY_ENABLED); CODE(AS_COMPOSITE_ENGINE_LAST); + // CompositeOverlay + CODE(AS_COMPOSITE_OVERLAY_CREATE); + CODE(AS_COMPOSITE_OVERLAY_INVALIDATE); + CODE(AS_COMPOSITE_OVERLAY_MOVE); + CODE(AS_COMPOSITE_OVERLAY_QUIT); + CODE(AS_COMPOSITE_OVERLAY_FOLLOW_MOUSE); + CODE(AS_COMPOSITE_OVERLAY_SHOW); + CODE(AS_COMPOSITE_OVERLAY_COMPOSITING); + CODE(AS_COMPOSITE_OVERLAY_FRAME); + CODE(AS_COMPOSITE_OVERLAY_EFFECTS); + CODE(AS_COMPOSITE_OVERLAY_DESTROY); + // BPicture definitions CODE(AS_CREATE_PICTURE); CODE(AS_DELETE_PICTURE); diff --git a/src/servers/app/ProfileMessageSupport.h b/src/servers/app/ProfileMessageSupport.h index a31f201..6d55465 100644 --- a/src/servers/app/ProfileMessageSupport.h +++ b/src/servers/app/ProfileMessageSupport.h @@ -13,6 +13,7 @@ void string_for_message_code(uint32 code, BString& string); +const char* string_for_message_code(uint32 code); #endif // PROFILE_MESSAGE_SUPPORT_H diff --git a/src/servers/app/drawing/compositing/CompositeEngine.cpp b/src/servers/app/drawing/compositing/CompositeEngine.cpp index 997483a..30c4f4b 100644 --- a/src/servers/app/drawing/compositing/CompositeEngine.cpp +++ b/src/servers/app/drawing/compositing/CompositeEngine.cpp @@ -543,10 +543,37 @@ CompositeEngine::AddDirty(const BRegion& dirty, bool visible) } +void +CompositeEngine::AddDirty(const BRect& dirty, bool visible) +{ + BAutolock _(fDirtyLock); + + fScreenStates->SetDirty(dirty, visible); +} + + // #pragma mark Window Modes void +CompositeEngine::DisableUpdates(const BRegion& region) +{ + BAutolock _(fDirtyLock); + + fScreenStates->Block(region); +} + + +void +CompositeEngine::EnableUpdates(const BRegion& region) +{ + BAutolock _(fDirtyLock); + + fScreenStates->Unblock(region); +} + + +void CompositeEngine::Move(CompositeWindow* window, const BRect& from, const BRect& to) { // if (fEffectsEnabled && fEffectsManager != NULL){ diff --git a/src/servers/app/drawing/compositing/CompositeEngine.h b/src/servers/app/drawing/compositing/CompositeEngine.h index 22d6f3a..fae8116 100644 --- a/src/servers/app/drawing/compositing/CompositeEngine.h +++ b/src/servers/app/drawing/compositing/CompositeEngine.h @@ -80,6 +80,11 @@ public: float AverageFPS() const; void AddDirty(const BRegion&, bool visible); + void AddDirty(const BRect&, bool visible); + + void DisableUpdates(const BRegion&); + void EnableUpdates(const BRegion&); + void Move(CompositeWindow*, const BRect& from, const BRect& to); diff --git a/src/servers/app/drawing/compositing/CompositeOverlay.cpp b/src/servers/app/drawing/compositing/CompositeOverlay.cpp index 9024491..dc12dde 100644 --- a/src/servers/app/drawing/compositing/CompositeOverlay.cpp +++ b/src/servers/app/drawing/compositing/CompositeOverlay.cpp @@ -3,6 +3,10 @@ #include "CompositeOverlay.h" +#include "ProfileMessageSupport.h" +#include "RapidDebug.h" +#include "ServerProtocol.h" + namespace BPrivate{ CompositeOverlay::CompositeOverlay(BRect frame) @@ -21,7 +25,8 @@ CompositeOverlay::CompositeOverlay(BRect frame) fFollowingMouse(false), fIsQuitting(false), fIsRunning(false), - fClientConnected(false) + fClientConnected(false), + fLastCode(0) {} @@ -210,12 +215,120 @@ CompositeOverlay::_PortLooperThread(void *_ptr) status_t CompositeOverlay::_PortLooper() { - int32 code = -1; + int32 code = -1, reply = -1; - while (fLink->GetNextMessage(code) == B_OK){ - // switch code... + BString string; - } + while (fLink->GetNextMessage(code) == B_OK){ + switch (code){ + case AS_COMPOSITE_OVERLAY_CREATE: + break; // we shouldn't get this here, should we? + case AS_COMPOSITE_OVERLAY_INVALIDATE:{ + if (fLink->ReadString(string) != B_OK){ + _LOGF("Failure reading command string on %s\n", + string_for_message_code(code)); + break; + } + + BRegion region; + + if (string == "BRect"){ + BRect rect; + fLink->Read<BRect>(&rect); + region.Include(rect); + + }else if (string == "BRegion"){ + fLink->ReadRegion(®ion); + } + else + _LOGF("CompositeOverlay: INVALIDATE\"%s\" Unhandled\n", + string.String()); + + // prevent updates to the screen area affected until + // we have finished drawing. + gCompositeEngine->DisableUpdates(region); + + for (int32 i = 0; i < region.CountRects(); ++i){ + fLink->StartMessage(code); + fLink->Attach<BRect>(region.RectAt(i)); + fLink->FlushWithReply(reply); + if (reply != B_OK) + break; + + } + + gCompositeEngine->AddDirty(region, true); + gCompositeEngine->EnableUpdates(region); + + break; + } + case AS_COMPOSITE_OVERLAY_MOVE: + { + if (fLink->ReadString(string) != B_OK){ + _LOGF("Failure reading command string on %s\n", + string_for_message_code(code)); + break; + } + + IntRect newFrame = fFrame; + + float x = 0, y = 0; + + if (string == "MoveTo()"){ + fLink->Read<float>(&x); + fLink->Read<float>(&y); + + newFrame.right = (int32)x + newFrame.Width(); + newFrame.left = (int32)x; + newFrame.bottom = (int32)y + newFrame.Height(); + newFrame.top = (int32)y; + } else if (string == "MoveBy()"){ + fLink->Read<float>(&x); + fLink->Read<float>(&y); + newFrame.OffsetBy(x, y); + } + + BRegion dirty; + dirty.Include((BRect)newFrame); + dirty.Include((BRect)fFrame); + fFrame = newFrame; + gCompositeEngine->AddDirty(dirty, true); + break; + } + + case AS_COMPOSITE_OVERLAY_QUIT: + { + fLink->StartMessage(code); + fLink->Attach<bool>(true); + fLink->FlushWithReply(reply); + + if (reply == B_OK) + Quit(true); + + break; + } + + case B_ERROR: + case B_OK: + case B_UNSUPPORTED: + { + // UH OH!! + + _LOGF("CompositeOverlay: %s may have not handled its reply!", + string_for_message_code(fLastCode)); + + break; + } + + default: + _LOGF("CompositeOverlay: Unhandled message: %li (%s)\n", + code, string_for_message_code(code)); + break; + } // end switch + + fLastCode = code; + + } // end message lop return B_ERROR; diff --git a/src/servers/app/drawing/compositing/CompositeOverlay.h b/src/servers/app/drawing/compositing/CompositeOverlay.h index 93ded4f..c436d1a 100644 --- a/src/servers/app/drawing/compositing/CompositeOverlay.h +++ b/src/servers/app/drawing/compositing/CompositeOverlay.h @@ -95,6 +95,8 @@ private: fIsQuitting : 1, fIsRunning : 1, fClientConnected : 1; + + int32 fLastCode; }; }; // namespace BPrivate diff --git a/src/servers/app/drawing/compositing/CompositeScreenStates.cpp b/src/servers/app/drawing/compositing/CompositeScreenStates.cpp index ba91863..429f475 100644 --- a/src/servers/app/drawing/compositing/CompositeScreenStates.cpp +++ b/src/servers/app/drawing/compositing/CompositeScreenStates.cpp @@ -5,7 +5,8 @@ CScreenStates::CScreenStates() : MultiLocker("CScreenStates"), - fAlphaModeRegionValid(false) + fAlphaModeRegionValid(false), + fBlockingEnabled(true) {} @@ -60,6 +61,62 @@ CScreenStates::UnsetAllDirty() void +CScreenStates::DisableBlocking() +{ + fBlockingEnabled = false; +} + + +void +CScreenStates::EnableBlocking() +{ + fBlockingEnabled = true; +} + + +bool +CScreenStates::IsBlockingEnabled() const +{ + return fBlockingEnabled; +} + + +void +CScreenStates::Block(const BRegion& region) +{ + fBlockedRegion.Include(®ion); +} + + +void +CScreenStates::Block(const BRect& rect) +{ + fBlockedRegion.Include(rect); +} + + +void +CScreenStates::Unblock(const BRegion& region) +{ + fBlockedRegion.Exclude(®ion); +} + + +void +CScreenStates::Unblock(const BRect& rect) +{ + fBlockedRegion.Exclude(rect); +} + + +void +CScreenStates::UnsetAllBlocked() +{ + fBlockedRegion.MakeEmpty(); +} + + +void CScreenStates::SetAlpha(const BRegion& region) { fAlphaRegion.Include(®ion); @@ -105,6 +162,8 @@ CScreenStates::GetCopyMode(BRegion& out) out.Include(&fAlphaModeRegion); out.Include(&fDirtyForegroundRegion); + if (fBlockingEnabled) + out.Exclude(&fBlockedRegion); return (fAlphaModeRegion.CountRects() != 0 || fDirtyForegroundRegion.CountRects() != 0); } @@ -120,6 +179,8 @@ CScreenStates::GetAlphaMode(BRegion& out) } out.Include(&fAlphaModeRegion); + if (fBlockingEnabled) + out.Exclude(&fBlockedRegion); return fAlphaModeRegion.CountRects() != 0; } @@ -159,7 +220,17 @@ CScreenStates::CopyInto(CScreenStates* states) states->fAlphaRegion.Include(&fAlphaRegion); states->fDirtyForegroundRegion.Include(&fDirtyForegroundRegion); states->fDirtyBackgroundRegion.Include(&fDirtyBackgroundRegion); + states->fBlockedRegion.Include(&fBlockedRegion); } +void +CScreenStates::CopyFrom(CScreenStates* states) +{ + fAlphaRegion.Include(&states->fAlphaRegion); + fDirtyForegroundRegion.Include(&states->fDirtyForegroundRegion); + fDirtyBackgroundRegion.Include(&states->fDirtyBackgroundRegion); + fBlockedRegion.Include(&states->fBlockedRegion); +} + diff --git a/src/servers/app/drawing/compositing/CompositeScreenStates.h b/src/servers/app/drawing/compositing/CompositeScreenStates.h index 2e130d4..232b7fe 100644 --- a/src/servers/app/drawing/compositing/CompositeScreenStates.h +++ b/src/servers/app/drawing/compositing/CompositeScreenStates.h @@ -6,6 +6,7 @@ 1. Background dirty windows (hidden from view, not minimized) 2. Foreground dirty windows 3. Visible alpha-mode region + 4. Blocked update region The main advantage and purpose of this object is to off-load the computing task to threads other than those created by the CompositeEngine. When it @@ -65,6 +66,19 @@ public: void UnsetAllDirty(); + void DisableBlocking(); + void EnableBlocking(); + + bool IsBlockingEnabled() const; + + void Block(const BRegion&); + void Block(const BRect&); + + void Unblock(const BRegion&); + void Unblock(const BRect&); + + void UnsetAllBlocked(); + void SetAlpha(const BRegion&); void SetAlpha(const BRect&); @@ -94,11 +108,13 @@ private: fAlphaModeRegion.MakeEmpty(); WriteUnlock();} - bool fAlphaModeRegionValid; + bool fAlphaModeRegionValid : 1, + fBlockingEnabled : 1; BRegion fAlphaRegion, fDirtyForegroundRegion, fDirtyBackgroundRegion, + fBlockedRegion, fAlphaModeRegion; };