[haiku-commits] BRANCH looncraz-github.compositing - src/servers/app/drawing/compositing src/servers/app src/kits/interface headers/private/app src/kits/app

  • From: looncraz-github.compositing <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 24 Apr 2012 09:48:28 +0200 (CEST)

added 33 changesets to branch 'refs/remotes/looncraz-github/compositing'
old head: 0000000000000000000000000000000000000000
new head: fe7207954e1107589c440b9181a85a2a4fcc352f

----------------------------------------------------------------------------

8bcdc04: Doing thing right - I hope
  
  Brought CompositeEngine.h more inline with app_server and fixed numerous 
little errors (I hate USB keyboards...).
  
  Changed UpdateQueue into HWUpdateQueue and created a new UpdateQueue as, 
basically, an interface class.
  Created CompositeUpdateQueue to act as a final-gathering place for areas in 
the back-buffer which need to be copied to the front buffer.
  
  Begin fleshing out CompositingPerfmon.
  
  Verified clean build status, have not verified run-time sanity, though there 
should be no effects at this point other than a slightly larger binary.

58fcae3: Finally a working man's commit...
  
  Much future planning (immediate future...), app_server communication protocol 
setup started, fixed a few things, changed some more, yadda yadda.
  
  All compiles, but will not link.  That is intentional (lets me know where I 
am going next in case I forget to add a note to my TODO).

ca74099: Major commit
  
  Re-oriented ComositeEngine scrap pieces from CAFE::RenderEngine, namely 
removing performance modes - as these aren't likely needed int the limited role 
in the app_server.
  If anything, the app_server will only need three modes: slow(5hz), 60hz, 
@refresh, which is better handled with SetSlowMode() and 
SetUpdateEveryRefresh().
  
  Moved special accessors to CompositingPrivate.  Prepared app_server port 
communication, implemented some BWindow changes (SetDrawingMode()), prepare for 
special
  full-screen modes to prevent unneeded updates from the back coming forward.
  
  Created WindowBuffer, which will be atttached to a Painter with a new method 
to render the buffer directly, which is attached to a standard RenderEngine, 
which will be generated by
  the CompsiteHWInterface.  WindowBuffer will collect updated rects and the 
CompositeEngine will prioritize updates front-to-back, ceasing updates when a 
new frame is to be renderred
  - but not before completing updates for any active WindowBuffer.
  
  While WindowBuffer is active with the CompositeEngine, the client will be 
unable to make drawing changes, so we will push as many threads to each 
WindowBuffer as possible, with each
  dirty rect possibly being handled by a separate thread/core and unlock that 
WindowBuffer as quickly as possible.

5df5c10: Adding needed funcitonality to Window:
  
  Ability to use WindowBuffer (for compositing OR caching).
  
  Bring numerous other objects in line with changes.
  
  Take into account requirements for hardware acceleration.
  
  CompositeHWInterface is now an AccelerantHWInterface.
  
  Trying to limit requirements in the future for acceleration.
  
  NOTE:  the build will not link at this point, still on purpose...

55b3b78: Implement some missing functions.
  
  Found some lacking areas, and implemented missing WindowBuffer functions.
  
  CompositeEngine is only hold-up until link success.

9cd2054: Various tidbits.

d6c9717: Message Handling
  
  Setup message handling for compositing.
  
  The CompositeEngine will handle all of its own requests.
  
  This is merely a prelude before setting up a route around ServerApp to 
expediate communications.
  
  Purpose being that some messages will undoubtedly be very time sensitive... 
and having all handling code in one place is quite nice.
  
  Began changes and made first runs of modified app_server (without incident, 
but no regression testing-yet).
  
  app_server now builds.
  
  Modified binaries thus far: libbe.so, app_server

86d79d7: Bug fixes
  
  Test run with compositing enabled to trace down bugs.  Found several - as 
expected.

79c4de7: Adapt view to local buffer coordinates for drawing.
  
  Hoping this way works - it did eliminate all segment violations up to the 
Desktop bitmap draw, so we are no longer overunning the buffers it would seem...
  
  This is being kept as its own commit so it can be easily undone later, or 
referenced.

3823042: Working out the kinks...
  
  As we are now much more sensitive to writing outside of a View's bounds, we 
have to make adjustments...
  
  I believe I will be making Painter more aware of it's buffer's limitations, 
and to act accordingly to prevent segment violations.
  
  At this point, app_server can run in compositing mode, though nothing is 
painted on the screen.  However, with very little effort (just clicking around) 
we find
  ourselves with a segment violation in Window SeetDrawingBuffer(), IIRC...  
next commit ;-)

a649fe9: Re-orienting to mixed-compositing (temporarily)
  
  Removed Window::SetDrawingMode in preference to the original 
B_RENDER_COMPOSITE window flag.
  The app_server internals make so many assumptions that drawing is occuring 
directly in the screen coordinate space that I am having surprising difficulty 
getting even a single
  Window to draw into its own WindowBuffer without some code blasting past the 
boundaries (and thus crashing).
  
  Decorators now draw directly into the screen buffer, but will soon be 
rewritten to draw into the  over-provisioned WindowBuffers of their 'owning' 
windows.
  
  Currently, using the app_server without compositing enabled is going to be 
fruitless, and compositing still defaults to disabled, so don't expect to build 
a usable app_server -
  though it does build without issue.
  
  Modified View to use ConvertForDrawing instead of ConvertToScreenForDrawing.  
The functions are still very rudimentary, will be cloned in WindowBuffer, and 
the View functions will
  call into WindowBuffer to ascertain the proper drawing area.
  
  Further, the disconnect of DrawingEngine and its owner must be dissolved.  
And Painter with its buffer...
  
  Both must be made aware of their drawing space so they do no attempt to write 
outside of it, but intelligently clip their drawing.  Each with their own 
degree of agressiveness and
  reaction.

7104d4b: Assorted tidbits
  
  Found chicken/egg problem in Window constructor which was causing problems.  
Things are much better now.
  
  Decided against using UpdateQueue in preference to dual BRegion for the 
WindowBuffer.  Window's UpdateSession may be used instead when I get further 
along.
  
  Decorators are very confused as to dirty regions, but I am preparing to 
over-provision WindowBuffer to optimize resize performance and to permit room 
to draw the decorator directly
  into the WindowBuffer.
  
  Clipping will prevent window content spill-over, but decorators will be able 
to draw over the window (but should avoid it, naturally).
  
  Decorator changes are coming soon - the order of initialization may change 
radically - but it may not...

d4f54d1: Re-orientation to new model...
  
  -Decided to change the methodology for View's ConvertForDrawing() to convert 
up through the parents all of the way to the window.  The window then does the 
final conversion based
  upon its type:
  
        Window: converts drawing to screen coordinate space
        OffscreenWindow: does no further conversion
        CompositeWindow: converts to WindowBuffer coordinate space
  
        (Others will inherit the behavior from Window, but I will investigate 
the need to override such behavior.)
  
  -Virtualized many functions in Window to facilitate a functional 
CompositeWindow typee so as to keep the code paths separate.
  
  -Making first steps to have WindowBuffer stay alive even after a Window's 
Quit() or destruction until all referencing objects have adapted or been 
destroyed.
        WindowBuffer is now a BReferenceable & only BReference<WindowBuffer> 
will be passed around.
        TODO: DrawingEngine will manually call AcquireReference() and 
ReleaseReference() if casting to WindowBuffer succeeds.
                Why: this greatly simplifies locking, and also permits 
lazy-recycling of allocated buffer spaces in the future.
  
  I believe all other changes are in-ine with the abovee.
  
  This will not build.  Will probably spout out many many errors.
  
  Will certainly not link ;-)

7117024: Moving Along
  
  Further implementing CompositeWindow.
  
  Re-wrote WindowBuffer's _ResizeTo() function with tested & working code.
  
  Compiles, will not link.  Much work to go.

b59f6ce: Bug fix, misc...

e8b91bd: Fixes
  
  Non-compositing mode now mostly works properly again.
  
  There are probably a few bugs here and there, but they should be minor(or 
obvious).
  
  Ran into an interesting situation where View::ConvertToWindow() somehow 
converts all of the way to the screen, which makes no sense... somewhere the 
drawing instructions are being
  converted from window coordinates to screen coordinates - and I can't find 
it...
  
  I checked in both View.cpp files (src/kits, and src/servers/app), 
ServerWindow (which receives the drawing messages from BView), and the 
ConvertToParent() code to try and solve this
  dilemma.  I even had ever single view spout out its frame to make sure the 
view attached to the window had an origin of (0,0) - and they all did...
  
  Next commit will hopefully solve this...

443ba22: Bug fix
  
  Figured out the problem with View::ConvertForDrawing(*) - ConvertToParent 
when there is no parent results in an undesired result (though it seems like it 
shouldn't do anything.. the
  frame should be (0,0,rt, bt).

c52e7f2: Continuing progress.
  
  CompositeHWInterface taking over for AccelratedHWInterface.
  
  CompositeWindow taking over for Window (for non-offscren windows only).
  
  Temporary B_RENDER_COMPOSITE flag being utilized to force a single window 
into compositing for testing.
  
  Logging levels reduced to eliminate tested code-paths.  Further reductions 
forth-coming.
  
  DrawingEngine now capable of having a RenderingBuffer manually set via its 
public API. RenderingBuffer now capable of being aware of such changes to 
augment lazy-allocation
  techniques - or other uses (such as knowing when we are no longer being 
modified...).
  
  Builds.  Runs.  Works.  Drawing doesn't seem to be re-routed to set 
RenderingBuffer, so there is some logging in place to trace that issue...

eb34894: Bug fixes & more prep-work
  
  WindowBuffer:
        fWindowFrame was not being updated.
        Over-provisioning was being added at the wrong time - thereby not bein 
applied at all.
        Cleaned up the code and removed interim window frame as the window 
frame must change for each and every resize event.
  
  CompositeWindow
        Setup to use a new method to temporarily mark a test window as 
compositing.
  
  Decorator:
        Preparing to drastically change how drawing is handled in Decorator.
        Will implement BView-style drawing interfaces, and hide much of the 
tedium.
        This is important as a Decorator may draw in foreign coordinate systems 
- such as WindowBuffer's.
        All frames and drawing will be relative to the window frame.
        Move events will need to be blocked entirely from a custom decorator's 
awareness.
  
  app_server builds & runs.  An odd memory leak is still occuring in relation, 
I believe, to WindowBuffer... which is an odd situation... after WindowBuffer 
is destroyed, some RAM
  seems to not be returned to the system.  Will need to chase this down.

1e36fee: Correct oversight.
  
  WindowBuffer was meant to hold its largest size in both dimensions, but any 
time a new max was achieved in either dimension it'd lose the other dimension's 
previous setting.
  
  This commit resolves this.
  
  On a side note:  verified performance increase of other commits in 
non-compositing mode.  Slightly faster than anticipated.

bd713a3: Test drawing WindowBuffer to frame buffer
  
  CompositeEngine::Draw() working better - also not locking exclusively & for a 
much shorter duration.
  
  There seems to be some issues with DrawBuffer(), it draws very quickly, but 
there are large black regions seemingly even outside the drawing region... very 
strange.
  
  Created AlphaRegion to hold and compute the WindowBuffer region's alpha areas 
as well as the screen's for fast reference.  The theory is that the screen's 
alpha
  region will be updated for every window movement (focus changes, moving 
windows, minmizations, blocking, etc...) and each WindowBuffer's region will be 
largely
  stagnant, or will change relatively slowly.  It is one consideration into the 
forthcoming Compositing Optimization Guide for Haiku application developers.

537a2ca: Cleaned up CompositingPrivate
  
  Haven't even tried compiling these changes.
  
  RenderSession may or may not persist, just exploring matters...
  
  Having hard drive difficulties so I thought it best to push these changes up 
ASAP.

388e1af: Coding with headache == hard
  
  Correcting mistakes and completing initial CompositingPrivate changes.
  
  Removed RenderSession, may have windows maintain visible regions.
  
  Compiles - haven't tested running yet, but there should be no new issues.

6fe0747: More client-server comms
  
  Flesh out more of the CompositeEngine communication protocol.  There is 
currently a stalling issue with getCompositingConfig() in CompositingProvate.
  
  Began to flesh out the fundamental server-side requirements for 
BCompositeOverlay, which is a BBitmap which accepts views and will provide 
numerous special-purpose features (such as
  locking to mouse movement and likely other conditions).
  
  Decided to make over-provisioning configurable.  Also re-worked 
BWindow::_RequestEffect() to not use a BMessage by internally converting an 
uint32 to BPrivate::effect_type.
  
  Builds & runs.  Have observed a performance increase in non-composited mode.  
I believe this is due to the optimizations in the code-paths for 
ConvertForDrawing vs
  ConvertToScreenForDrawing.  The latter, IIRC, used a side-effect to work up 
view hierarchy which resulted in numerous vtable lookups.  Don't quote me on 
that though... long time
  since I looked at the original code ;-)  My guess of +0.5fps in 
CompositePerfTest3 was about spot-on, seeing about +0.75fps in VMWare.

67b90e3: CompositeOverlay
  
  More CompositeOverlay work.
  
  I believe this should remain public API, but perhaps not until compositing is 
more stabilized.

6ad2af3: BCompositeOverlay
  
  Public API should now be final.  Client code should be functional.  
Server-side code still just a place-holder.
  
  Compiles & links once again.
  
  TODO: need to convert rgb_color to a fill pattern based upon BBitmap's color 
space rather than using the accelerant's conversion in case the video driver 
uses a different pattern
  and will convert the bitmap before displaying on-screen.  I doubt this is a 
problem on x86 these days, but other platforms will likely also desire the 
compositing features.

090b450: Server-side CompositeOverlay
  
  Setting up the server-side of things for BCompositeOverlay.
  
  Also touched a couple of other areas as I ran into things that need to be 
implemented now or in the future.
  
  Compiles - will not link (missing CompositeEngine::Hide(CompositeOverlay*) 
and Show(...)).

4687592: Adjust to requirements.
  
  Found most of the reason why the drawing was all weird... mostly due to 
clipping - which I anticipated...
  
  Further investigated the conversion requirements, and stripped out unneeded 
virtual overrides.
  
  Making some attempts to improve performance, I have investigated the need for 
alpha regions - determined they are more vital than ever if we hope to have 
CPU-based compositing with
  an acceptable performance level...
  
  Preparing for cursor overlays, and a few other tidbits.

1489f21: Coordinate conversion & optimization
  
  Added ability to convert back from the window's coordinate space to a view 
for various current and future uses.
  
  "Profiled" code paths to determine usage and performance, decided 
optimization was called for - and was surprised by the end result.  
CompositePerfTest3 went from 24FPS to 27FPS -
  with just 12bytes or so of RAM per view extra...  Also cleans up the code 
nicely ;-)
  
  Wish I had more time... and that I weren't sick :-(

76dfc16: ScreenStateGrid & more
  
  ScreenStateGrid represents the visible screen as a grid of cells.  It is just 
an unfinished header at this point.
  
  Made changes to some comments to better suit the understandability to the 
uninitiated (i.e.... everyone else but me...).
  
  Also preparing CompositeEngine to use ScreenStateGrid, and to re-purpose 
Desktop's window listing rather than having its own.  Z-order will be handled 
by sorting the Desktop's
  window list.  The desktop window will be window 0, and the top-most window 
will be at the highest index.
  
  Also a bit of extra loop unrolling to help speed up the final render task - 
more unrolling may be worthwhile, but it could be counter-productive at the 
same time...

e12c27c: Poor scaling, so re-designed
  
  Quick-n-dirty performance test of a faux-ScreenStateGrid determined that the 
grid method would have poor scalability at higher resolutions.  It was faster 
at 1024x768 and below, but
  from there became slower.
  
  Mutated ScreenStateGrid into CompositeScreenStates, which holds numerous 
regions an interplexes them to gain the necessary output regions.

57a09ef: Re-orient towards CompositeScreenStates
  
  Haven't test CompositeScreenStates yet, so that is next on my todo list (off 
git).
  
  CompositeEngine's crude test-mode Draw() function has been gutted as it was 
no longer usable.
  
  Once CompositeScreenStates is verified, I will be moving to direct full-mode 
compositing of all windows, working out the kinks as they come along.

fe72079: CScreenStates verified (well enough for now, anyway)
  
  No changes needed to CScreenStates - seems to work like a charm.  Re-oriented 
towards using it, will be working window events back up the (logical) object 
stack to assure all is
  well.
  
  Next temporary draw routine will cycle through every window, in order, in the 
dirty region and draw them.  It will then perform the alpha-mode render.  
Performance will be sad, but
  it will be required to make further progress.

                                         [ looncraz <looncraz@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

64 files changed, 6316 insertions(+), 176 deletions(-)
headers/os/interface/Bitmap.h                      |    1 +
headers/os/interface/CompositeOverlay.h            |  158 ++++
headers/os/interface/Window.h                      |   11 +-
headers/private/app/CompositingPrivate.h           |  190 ++++
headers/private/app/ServerProtocol.h               |   31 +
src/kits/app/CompositingPrivate.cpp                |  395 ++++++++
src/kits/app/Jamfile                               |    1 +
src/kits/interface/CompositeOverlay.cpp            |  575 ++++++++++++
src/kits/interface/Jamfile                         |    1 +
src/kits/interface/Window.cpp                      |   77 ++-
src/servers/app/AppServer.cpp                      |    3 +
src/servers/app/BitmapManager.cpp                  |   21 +-
src/servers/app/Jamfile                            |    1 +
src/servers/app/OffscreenServerWindow.cpp          |    8 +-
src/servers/app/OffscreenWindow.cpp                |   32 +-
src/servers/app/OffscreenWindow.h                  |    6 +
src/servers/app/ProfileMessageSupport.cpp          |   18 +-
src/servers/app/RapidDebug.h                       |   36 +
src/servers/app/RenderingBuffer.h                  |    5 +
src/servers/app/Screen.cpp                         |    2 +-
src/servers/app/ScreenManager.cpp                  |    4 +-
src/servers/app/ServerApp.cpp                      |   21 +-
src/servers/app/ServerPicture.cpp                  |   40 +-
src/servers/app/ServerWindow.cpp                   |  157 +++-
src/servers/app/View.cpp                           |  206 ++++-
src/servers/app/View.h                             |   61 +-
src/servers/app/Window.cpp                         |  220 +++++-
src/servers/app/Window.h                           |   49 +-
src/servers/app/decorator/Decorator.h              |    1 +
src/servers/app/drawing/AccelerantHWInterface.h    |    3 +-
src/servers/app/drawing/BitmapBuffer.cpp           |    1 +
src/servers/app/drawing/BitmapBuffer.h             |    2 +-
src/servers/app/drawing/DrawingEngine.cpp          |   68 ++-
src/servers/app/drawing/DrawingEngine.h            |    9 +-
src/servers/app/drawing/HWInterface.cpp            |    4 +-
src/servers/app/drawing/HWInterface.h              |    5 +-
src/servers/app/drawing/Jamfile                    |    2 +
src/servers/app/drawing/Painter/Painter.cpp        |   38 +-
src/servers/app/drawing/Painter/Painter.h          |    3 +
src/servers/app/drawing/UpdateQueue.cpp            |   14 +-
src/servers/app/drawing/UpdateQueue.h              |    9 +-
.../app/drawing/compositing/AlphaRegion.cpp        |  113 +++
src/servers/app/drawing/compositing/AlphaRegion.h  |   78 ++
.../app/drawing/compositing/CompositeEffect.h      |   36 +
.../app/drawing/compositing/CompositeEngine.cpp    |  773 ++++++++++++++++
.../app/drawing/compositing/CompositeEngine.h      |  175 ++++
.../drawing/compositing/CompositeEngineClient.cpp  |   28 +
.../drawing/compositing/CompositeEngineClient.h    |   26 +
.../drawing/compositing/CompositeHWInterface.cpp   |  128 +++
.../app/drawing/compositing/CompositeHWInterface.h |   47 +
.../app/drawing/compositing/CompositeOverlay.cpp   |  235 +++++
.../app/drawing/compositing/CompositeOverlay.h     |  102 ++
.../drawing/compositing/CompositeScreenStates.cpp  |  165 ++++
.../drawing/compositing/CompositeScreenStates.h    |  108 +++
.../app/drawing/compositing/CompositeWindow.cpp    |  416 +++++++++
.../app/drawing/compositing/CompositeWindow.h      |  108 +++
.../app/drawing/compositing/CompositingPerfmon.cpp |  312 +++++++
.../app/drawing/compositing/CompositingPerfmon.h   |  115 +++
src/servers/app/drawing/compositing/Jamfile        |   28 +
.../app/drawing/compositing/WindowBuffer.cpp       |  739 +++++++++++++++
src/servers/app/drawing/compositing/WindowBuffer.h |  233 +++++
src/servers/app/drawing/drawing_support.h          |   34 +-
.../app/drawing/remote/RemoteHWInterface.cpp       |    2 +-
src/servers/app/drawing/remote/RemoteHWInterface.h |    2 +-

############################################################################

Commit:      8bcdc04f4d70593563c525f07d5dea55133a13f2

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Fri Mar 23 02:10:44 2012 UTC

Doing thing right - I hope

Brought CompositeEngine.h more inline with app_server and fixed numerous little 
errors (I hate USB keyboards...).

Changed UpdateQueue into HWUpdateQueue and created a new UpdateQueue as, 
basically, an interface class.
Created CompositeUpdateQueue to act as a final-gathering place for areas in the 
back-buffer which need to be copied to the front buffer.

Begin fleshing out CompositingPerfmon.

Verified clean build status, have not verified run-time sanity, though there 
should be no effects at this point other than a slightly larger binary.

----------------------------------------------------------------------------

diff --git a/src/servers/app/drawing/HWInterface.cpp 
b/src/servers/app/drawing/HWInterface.cpp
index 8e448eb..4c8dd5c 100644
--- a/src/servers/app/drawing/HWInterface.cpp
+++ b/src/servers/app/drawing/HWInterface.cpp
@@ -21,7 +21,7 @@
 #include "DrawingEngine.h"
 #include "RenderingBuffer.h"
 #include "SystemPalette.h"
-#include "UpdateQueue.h"
+#include "HWUpdateQueue.h"
 
 
 using std::nothrow;
@@ -313,7 +313,7 @@ HWInterface::SetAsyncDoubleBuffered(bool doubleBuffered)
        if (doubleBuffered) {
                if (fUpdateExecutor != NULL)
                        return;
-               fUpdateExecutor = new (nothrow) UpdateQueue(this);
+               fUpdateExecutor = new (nothrow) HWUpdateQueue(this);
                AddListener(fUpdateExecutor);
        } else {
                if (fUpdateExecutor == NULL)
@@ -355,12 +355,12 @@ HWInterface::Invalidate(const BRect& frame)
 {
        if (IsDoubleBuffered()) {
 #if 0
-// NOTE: The UpdateQueue works perfectly fine, but it screws the
+// NOTE: The HWUpdateQueue works perfectly fine, but it screws the
 // flicker-free-ness of the double buffered rendering. The problem being the
-// asynchronous nature. The UpdateQueue will transfer regions of the screen
+// asynchronous nature. The HWUpdateQueue will transfer regions of the screen
 // which have been clean at the time we are in this function, but which have
 // been damaged meanwhile by drawing into them again. All in all, the
-// UpdateQueue is good for reducing the number of times that the transfer
+// HWUpdateQueue is good for reducing the number of times that the transfer
 // is performed, and makes it happen during refresh only, but until there
 // is a smarter way to synchronize this all better, I've disabled it.
                if (fUpdateExecutor != NULL) {
diff --git a/src/servers/app/drawing/HWInterface.h 
b/src/servers/app/drawing/HWInterface.h
index ab0f7bb..630302d 100644
--- a/src/servers/app/drawing/HWInterface.h
+++ b/src/servers/app/drawing/HWInterface.h
@@ -29,7 +29,7 @@ class EventStream;
 class Overlay;
 class RenderingBuffer;
 class ServerBitmap;
-class UpdateQueue;
+class HWUpdateQueue;
 
 
 enum {
@@ -161,7 +161,7 @@ public:
        virtual status_t                        InvalidateRegion(BRegion& 
region);
        virtual status_t                        Invalidate(const BRect& frame);
        // while as CopyBackToFront() actually performs the operation
-       // either directly or asynchronously by the UpdateQueue thread
+       // either directly or asynchronously by the HWUpdateQueue thread
        virtual status_t                        CopyBackToFront(const BRect& 
frame);
 
 protected:
@@ -257,7 +257,7 @@ protected:
                        int                                     fVGADevice;
 
 private:
-                       UpdateQueue*            fUpdateExecutor;
+                       HWUpdateQueue*          fUpdateExecutor;
 
                        BList                           fListeners;
 };
diff --git a/src/servers/app/drawing/HWUpdateQueue.cpp 
b/src/servers/app/drawing/HWUpdateQueue.cpp
new file mode 100644
index 0000000..b6d5bb1
--- /dev/null
+++ b/src/servers/app/drawing/HWUpdateQueue.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2005-2008 Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#include "HWUpdateQueue.h"
+
+#include <new>
+#include <stdio.h>
+#include <string.h>
+
+
+//#define TRACE_UPDATE_QUEUE
+#ifdef TRACE_UPDATE_QUEUE
+#      include <FunctionTracer.h>
+#      include <String.h>
+
+       static int32 sFunctionDepth = -1;
+#      define CALLED(x...)     FunctionTracer _ft("HWUpdateQueue", 
__FUNCTION__, \
+                                                       sFunctionDepth)
+#      define TRACE(x...)      { BString _to; \
+                                                       _to.Append(' ', 
(sFunctionDepth + 1) * 2); \
+                                                       printf("%s", 
_to.String()); printf(x); }
+#else
+#      define CALLED(x...)
+#      define TRACE(x...)
+#endif
+
+
+// constructor
+HWUpdateQueue::HWUpdateQueue(HWInterface* interface)
+       :
+       UpdateQueue("AppServer_HWUpdateQueue"),
+       fQuitting(false),
+       fInterface(interface),
+       fUpdateExecutor(B_BAD_THREAD_ID),
+       fRetraceSem(B_BAD_SEM_ID),
+       fRefreshDuration(1000000 / 60)
+{
+       CALLED();
+       TRACE("this: %p\n", this);
+       TRACE("fInterface: %p\n", fInterface);
+}
+
+// destructor
+HWUpdateQueue::~HWUpdateQueue()
+{
+       CALLED();
+
+       Shutdown();
+}
+
+// FrameBufferChanged
+void
+HWUpdateQueue::FrameBufferChanged()
+{
+       CALLED();
+
+       Init();
+}
+
+// Init
+status_t
+HWUpdateQueue::Init()
+{
+       CALLED();
+
+       Shutdown();
+
+       fRetraceSem = fInterface->RetraceSemaphore();
+//     fRefreshDuration = fInterface->...
+
+       TRACE("fRetraceSem: %ld, fRefreshDuration: %lld\n",
+               fRetraceSem, fRefreshDuration);
+
+       fQuitting = false;
+       fUpdateExecutor = spawn_thread(_ExecuteUpdatesEntry, "update queue 
runner",
+               B_REAL_TIME_PRIORITY, this);
+       if (fUpdateExecutor < B_OK)
+               return fUpdateExecutor;
+
+       return resume_thread(fUpdateExecutor);
+}
+
+// Shutdown
+void
+HWUpdateQueue::Shutdown()
+{
+       CALLED();
+
+       if (fUpdateExecutor < B_OK)
+               return;
+       fQuitting = true;
+       status_t exitValue;
+       wait_for_thread(fUpdateExecutor, &exitValue);
+       fUpdateExecutor = B_BAD_THREAD_ID;
+}
+
+
+// _ExecuteUpdatesEntry
+int32
+HWUpdateQueue::_ExecuteUpdatesEntry(void* cookie)
+{
+       HWUpdateQueue *gc = (HWUpdateQueue*)cookie;
+       return gc->_ExecuteUpdates();
+}
+
+// _ExecuteUpdates
+int32
+HWUpdateQueue::_ExecuteUpdates()
+{
+       while (!fQuitting) {
+               status_t err;
+               if (fRetraceSem >= 0) {
+                       bigtime_t timeout = system_time() + fRefreshDuration * 
2;
+//                     TRACE("acquire_sem_etc(%lld)\n", timeout);
+                       do {
+                               err = acquire_sem_etc(fRetraceSem, 1,
+                                       B_ABSOLUTE_TIMEOUT | B_CAN_INTERRUPT, 
timeout);
+                       } while (err == B_INTERRUPTED && !fQuitting);
+               } else {
+                       bigtime_t timeout = system_time() + fRefreshDuration;
+//                     TRACE("snooze_until(%lld)\n", timeout);
+                       do {
+                               err = snooze_until(timeout, B_SYSTEM_TIMEBASE);
+                       } while (err == B_INTERRUPTED && !fQuitting);
+               }
+               if (fQuitting)
+                       return B_OK;
+               switch (err) {
+                       case B_OK:
+                       case B_TIMED_OUT:
+                               // execute updates
+                               if (fInterface->LockParallelAccess()) {
+                                       if (Lock()) {
+                                               int32 count = 
fUpdateRegion.CountRects();
+                                               if (count > 0) {
+                                                       
TRACE("CopyBackToFront() - rects: %ld\n", count);
+                                                       // NOTE: not using the 
BRegion version, since that
+                                                       // doesn't take care of 
leaving out and compositing
+                                                       // the cursor.
+                                                       for (int32 i = 0; i < 
count; i++)
+                                                               
fInterface->CopyBackToFront(
+                                                                       
fUpdateRegion.RectAt(i));
+                                                       
fUpdateRegion.MakeEmpty();
+                                               }
+                                               Unlock();
+                                       }
+                                       fInterface->UnlockParallelAccess();
+                               }
+                               break;
+                       default:
+                               return err;
+               }
+       }
+       return B_OK;
+}
+
diff --git a/src/servers/app/drawing/HWUpdateQueue.h 
b/src/servers/app/drawing/HWUpdateQueue.h
new file mode 100644
index 0000000..5834276
--- /dev/null
+++ b/src/servers/app/drawing/HWUpdateQueue.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2005-2008 Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef UPDATE_QUEUE_H
+#define UPDATE_QUEUE_H
+
+#include <List.h>
+#include <Locker.h>
+#include <OS.h>
+#include <Region.h>
+
+#include "HWInterface.h"
+#include "UpdateQueue.h"
+
+/*
+       For future reference, this is used in HWInterface and is called the
+       fUpdateExecutor.  It is meant to be used for double-buffering.
+*/
+
+class HWUpdateQueue : public UpdateQueue, public HWInterfaceListener {
+ public:
+                                                               
HWUpdateQueue(HWInterface* interface);
+       virtual                                         ~HWUpdateQueue();
+
+       virtual void                            FrameBufferChanged();
+
+                       status_t                        Init();
+                       void                            Shutdown();
+
+ private:
+       static  int32                           _ExecuteUpdatesEntry(void 
*cookie);
+                       int32                           _ExecuteUpdates();
+
+       volatile bool                           fQuitting;
+                       HWInterface*            fInterface;
+
+                       thread_id                       fUpdateExecutor;
+                       sem_id                          fRetraceSem;
+                       bigtime_t                       fRefreshDuration;
+};
+
+#endif // UPDATE_QUEUE_H
diff --git a/src/servers/app/drawing/Jamfile b/src/servers/app/drawing/Jamfile
index ee5c465..b81efa3 100644
--- a/src/servers/app/drawing/Jamfile
+++ b/src/servers/app/drawing/Jamfile
@@ -7,6 +7,7 @@ UsePrivateSystemHeaders ;
 
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app ] ;
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app font ] ;
+UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing compositing ] ;
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter 
drawing_modes ] ;
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter 
font_support ] ;
@@ -18,6 +19,7 @@ StaticLibrary libasdrawing.a :
        BitmapBuffer.cpp
        drawing_support.cpp
        DrawingEngine.cpp
+       HWUpdateQueue.cpp
        MallocBuffer.cpp
        UpdateQueue.cpp
        PatternHandler.cpp
@@ -28,5 +30,6 @@ StaticLibrary libasdrawing.a :
        HWInterface.cpp
 ;
 
+SubInclude HAIKU_TOP src servers app drawing compositing ;
 SubInclude HAIKU_TOP src servers app drawing Painter ;
 SubInclude HAIKU_TOP src servers app drawing remote ;
diff --git a/src/servers/app/drawing/UpdateQueue.cpp 
b/src/servers/app/drawing/UpdateQueue.cpp
index d16a3e3..dd4394b 100644
--- a/src/servers/app/drawing/UpdateQueue.cpp
+++ b/src/servers/app/drawing/UpdateQueue.cpp
@@ -1,172 +1,40 @@
-/*
- * Copyright 2005-2008 Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
- * Distributed under the terms of the MIT License.
- */
-#include "UpdateQueue.h"
-
-#include <new>
-#include <stdio.h>
-#include <string.h>
 
+#include <Rect.h>
+#include <Region.h>
 
-//#define TRACE_UPDATE_QUEUE
-#ifdef TRACE_UPDATE_QUEUE
-#      include <FunctionTracer.h>
-#      include <String.h>
 
-       static int32 sFunctionDepth = -1;
-#      define CALLED(x...)     FunctionTracer _ft("UpdateQueue", __FUNCTION__, 
\
-                                                       sFunctionDepth)
-#      define TRACE(x...)      { BString _to; \
-                                                       _to.Append(' ', 
(sFunctionDepth + 1) * 2); \
-                                                       printf("%s", 
_to.String()); printf(x); }
-#else
-#      define CALLED(x...)
-#      define TRACE(x...)
-#endif
+#include "UpdateQueue.h"
 
 
-// constructor
-UpdateQueue::UpdateQueue(HWInterface* interface)
+UpdateQueue::UpdateQueue(const BString & name)
        :
-       BLocker("AppServer_UpdateQueue"),
-       fQuitting(false),
-       fInterface(interface),
-       fUpdateRegion(),
-       fUpdateExecutor(B_BAD_THREAD_ID),
-       fRetraceSem(B_BAD_SEM_ID),
-       fRefreshDuration(1000000 / 60)
-{
-       CALLED();
-       TRACE("this: %p\n", this);
-       TRACE("fInterface: %p\n", fInterface);
-}
-
-// destructor
-UpdateQueue::~UpdateQueue()
-{
-       CALLED();
-
-       Shutdown();
-}
-
-// FrameBufferChanged
-void
-UpdateQueue::FrameBufferChanged()
-{
-       CALLED();
-
-       Init();
-}
-
-// Init
-status_t
-UpdateQueue::Init()
-{
-       CALLED();
-
-       Shutdown();
-
-       fRetraceSem = fInterface->RetraceSemaphore();
-//     fRefreshDuration = fInterface->...
+       BLocker(name.String()),
+       fName(name)
+       {
+       }
 
-       TRACE("fRetraceSem: %ld, fRefreshDuration: %lld\n",
-               fRetraceSem, fRefreshDuration);
+// copy constructor
+UpdateQueue::UpdateQueue(const UpdateQueue& clone)
+       :
+       BLocker(clone.fName.String()),
+       fUpdateRegion(clone.fUpdateRegion),
+       fName(clone.fName)
+       {
+       }
 
-       fQuitting = false;
-       fUpdateExecutor = spawn_thread(_ExecuteUpdatesEntry, "update queue 
runner",
-               B_REAL_TIME_PRIORITY, this);
-       if (fUpdateExecutor < B_OK)
-               return fUpdateExecutor;
-               
-       return resume_thread(fUpdateExecutor);
-}
 
-// Shutdown
-void
-UpdateQueue::Shutdown()
-{
-       CALLED();
+UpdateQueue::~UpdateQueue()
+{      /*lock or test for lock?*/      }
 
-       if (fUpdateExecutor < B_OK)
-               return;
-       fQuitting = true;
-       status_t exitValue;
-       wait_for_thread(fUpdateExecutor, &exitValue);
-       fUpdateExecutor = B_BAD_THREAD_ID;
-}
 
 // AddRect
-void
-UpdateQueue::AddRect(const BRect& rect)
+void UpdateQueue::AddRect(const BRect& rect)
 {
        if (!rect.IsValid())
                return;
 
-       CALLED();
-
        if (Lock()) {
                fUpdateRegion.Include(rect);
                Unlock();
-       }
+       } // what about when we fail to obtain the lock!?!
 }
-
-// _ExecuteUpdatesEntry
-int32
-UpdateQueue::_ExecuteUpdatesEntry(void* cookie)
-{
-       UpdateQueue *gc = (UpdateQueue*)cookie;
-       return gc->_ExecuteUpdates();
-}
-
-// _ExecuteUpdates
-int32
-UpdateQueue::_ExecuteUpdates()
-{
-       while (!fQuitting) {
-               status_t err;
-               if (fRetraceSem >= 0) {
-                       bigtime_t timeout = system_time() + fRefreshDuration * 
2;
-//                     TRACE("acquire_sem_etc(%lld)\n", timeout);
-                       do {
-                               err = acquire_sem_etc(fRetraceSem, 1,
-                                       B_ABSOLUTE_TIMEOUT | B_CAN_INTERRUPT, 
timeout);
-                       } while (err == B_INTERRUPTED && !fQuitting);
-               } else {
-                       bigtime_t timeout = system_time() + fRefreshDuration;
-//                     TRACE("snooze_until(%lld)\n", timeout);
-                       do {
-                               err = snooze_until(timeout, B_SYSTEM_TIMEBASE);
-                       } while (err == B_INTERRUPTED && !fQuitting);
-               }
-               if (fQuitting)
-                       return B_OK;
-               switch (err) {
-                       case B_OK:
-                       case B_TIMED_OUT:
-                               // execute updates
-                               if (fInterface->LockParallelAccess()) {
-                                       if (Lock()) {
-                                               int32 count = 
fUpdateRegion.CountRects();
-                                               if (count > 0) {
-                                                       
TRACE("CopyBackToFront() - rects: %ld\n", count);
-                                                       // NOTE: not using the 
BRegion version, since that
-                                                       // doesn't take care of 
leaving out and compositing
-                                                       // the cursor.
-                                                       for (int32 i = 0; i < 
count; i++)
-                                                               
fInterface->CopyBackToFront(
-                                                                       
fUpdateRegion.RectAt(i));
-                                                       
fUpdateRegion.MakeEmpty();
-                                               }
-                                               Unlock();
-                                       }
-                                       fInterface->UnlockParallelAccess();
-                               }
-                               break;
-                       default:
-                               return err;
-               }
-       }
-       return B_OK;
-}
-
diff --git a/src/servers/app/drawing/UpdateQueue.h 
b/src/servers/app/drawing/UpdateQueue.h
index f8c5614..de5155f 100644
--- a/src/servers/app/drawing/UpdateQueue.h
+++ b/src/servers/app/drawing/UpdateQueue.h
@@ -1,41 +1,37 @@
+#ifndef UPDATE_QUEUE_INTERFACE_H
+#define UPDATE_QUEUE_INTERFACE_H
+
 /*
- * Copyright 2005-2008 Stephan Aßmus <superstippi@xxxxxx>. All rights reserved.
- * Distributed under the terms of the MIT License.
- */
-#ifndef UPDATE_QUEUE_H
-#define UPDATE_QUEUE_H
+       With the advent of the CompositeEngine it is better
+       to abstract the interface to minimize other code
+       changes and to make mode changes painless and fast.
+       
+       As such we have a copy constructor and handle the common
+       tasks here.
+       
+       It is VERY simple...
+       
+       This stores the areas which needs to be copied from the
+       back buffer to the front buffer (video card - normally).
+*/
 
-#include <List.h>
 #include <Locker.h>
-#include <OS.h>
 #include <Region.h>
+#include <Rect.h>
+#include <String.h>
 
-#include "HWInterface.h"
-
-
-class UpdateQueue : public BLocker, public HWInterfaceListener {
+class UpdateQueue: public BLocker{
  public:
-                                                               
UpdateQueue(HWInterface* interface);
-       virtual                                         ~UpdateQueue();
-
-       virtual void                            FrameBufferChanged();
-
-                       status_t                        Init();
-                       void                            Shutdown();
-
-                       void                            AddRect(const BRect& 
rect);
-
- private:
-       static  int32                           _ExecuteUpdatesEntry(void 
*cookie);
-                       int32                           _ExecuteUpdates();
+                                                       UpdateQueue(const 
BString& name);
+                                                       UpdateQueue(const 
UpdateQueue&);
+       virtual                                 ~UpdateQueue();
+       
+                       void                    AddRect(const BRect&);
+ protected:
+                       BRegion                 fUpdateRegion;
+                       BString                 fName;
+};
 
-       volatile bool                           fQuitting;
-                       HWInterface*            fInterface;
 
-                       BRegion                         fUpdateRegion;
-                       thread_id                       fUpdateExecutor;
-                       sem_id                          fRetraceSem;
-                       bigtime_t                       fRefreshDuration;
-};
+#endif
 
-#endif // UPDATE_QUEUE_H
diff --git a/src/servers/app/drawing/compositing/CompositeEngine.h 
b/src/servers/app/drawing/compositing/CompositeEngine.h
new file mode 100644
index 0000000..eb34d55
--- /dev/null
+++ b/src/servers/app/drawing/compositing/CompositeEngine.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2012, Haiku.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Joseph Groover <looncraz@xxxxxxxxxxx>
+ */
+#ifndef COMPOSITING_ENGINE_H
+#define COMPOSITING_ENGINE_H
+
+
+#include <ObjectList.h>
+#include <OS.h>
+#include <String.h>
+
+#include "HWInterface.h"
+#include "RenderingBuffer.h"
+#include "ServerBitmap.h"
+#include "UpdateQueue.h"
+
+/*
+       performance_mode determines the rate at which we will update changes
+       in the back-buffer into the front-buffer.
+       We batch updates together and change the performance mode based on the
+       amount of changes made, the area covered - along with app-requested 
+       performance modes (new API) or ServerWindow requests based on user
+       action (window resize/move, typing, etc...)
+       Just becauuse we are in, say, FULL_PERFORMANCE_MODE does not mean we
+       will actually be operating at a full 60 fps, that is just the reference
+       update interval (1/60th of a second [minus some time for overhead])     
+*/
+enum performance_mode{
+               STOP_PERFORMANCE_MODE = 0,      //   0  fps (screen off)
+               SLOW_PERFORMANCE_MODE = 5,      // <= 5 fps (sitting at the 
desktop)
+               MILD_PERFORMANCE_MODE = 15,     // < 15 fps (normal GUIs, low 
motion)
+               HIGH_PERFORMANCE_MODE = 30,     // < 30 fps (videos, moderate 
motion)
+               FULL_PERFORMANCE_MODE = 60,     // ~ 60 fps (animations, moving 
video)
+               SYNC_PERFORMANCE_MODE = 120,// @ refresh rate - up to 120hz
+               WILD_PERFORMANCE_MODE = 1000// max power! - up to 1000fps...
+};
+
+enum composite_mode{
+               NORMAL_COMPOSITE = 0//, // CPU[s] do[es] the work
+       //      ACCEL_COMPOSITE,        // GPU accelerated
+       //      MIXED_COMPOSITE,        // CPU does some, GPU does some
+       //      XGPUS_COMPOSITE,        // multiple GPUs for compositing
+       //      XHEAD_COMPOSITE         // treat monitors separately -
+                                                               // one 
workspace per monitor ;-)
+};
+
+/*
+       composite_client_type
+       
+       It is often useful for the CompositeEngine to know what type of client
+       is denying or making a request so as to react properly.
+       
+       Basically, if a Desktop requests STOP_PERFORMANCE_MODE, that means the
+       monitor has gone to black (or is going to sleep).  If a Window asks, we
+       will outright deny it.  If a workspace asks, and we are in 
XHEAD_COMPOSITE,
+       then we stop updates for the screen for that workspace, only increasing
+       when the workspace permits us.
+       
+       This allows us to not touch the code too much in the future.
+               
+       A CompositeEngineClient can identify itself as being of one of types
+       as follows:
+*/
+enum composite_client_type{
+       ANONYMOUS_COMPOSITE_CLIENT      = 0,
+       DESKTOP_COMPOSITE_CLIENT,
+       DESKTOPWINDOW_COMPOSITE_CLIENT,
+       WORKSPACE_COMPOSITE_CLIENT,
+       WINDOW_COMPOSITE_CLIENT,
+       SERVERWINDOW_COMPOSITE_CLIENT,
+       DIRECTWINDOW_COMPOSITE_CLIENT,
+       UPDATEQUEUE_COMPOSITE_CLIENT
+};
+
+class Window;
+
+class CompositeEngineClient{
+public:
+                                                               
CompositeEngineClient( const BString & name,
+                                                                       
composite_client_type = 
+                                                                               
ANONYMOUS_COMPOSITE_CLIENT);
+       virtual                                         
~CompositeEngineClient();
+       
+       virtual void                            CompositingEnabled(bool 
enabled) = 0;
+
+
+       // optional:
+
+       // if you need to do something BEFORE compositing takes over
+       // or before it ceases to render you need to override one of the 
following:
+       virtual void                            CompositingEnabling();
+       virtual void                            CompositingDisabling();
+       
+       virtual void                            
CompositingChanged(performance_mode,
+                                                                               
                        composite_mode);
+       virtual void                            CompositingPerformance(bool 
isLow = true);
+       
+       // affect operations
+       
+       // When a mode change is to be made we ask our clients if it is 
acceptable.
+       // Your opinion is just that - an opinion ;-)  Unless you are a 
Desktop...
+       virtual bool                            
CompositingModesRequested(performance_mode,
+                                                                               
                                        composite_mode);
+       
+                       
+                       void                            
MarkScreenRegionDirty(BRegion&);
+                       
+                       // tell the composite engine that you need to be 
treated better
+                       // or that you are being treated too well.
+                       // There are five (unnamed) priority levels (0-4)
+                       // everyone starts at zero (lowest priority).
+                       void                            
IncreaseCompositeClientPriority();
+                       void                            
DecreaseCompositeClientPriority();
+                       void                            
SetCompositeClientPriority(uint8);
+       
+                       uint8                           
CompositeClientPriorityLevel() const;
+                       
+                       // If requested mode (or higher) is achieved, true is 
returned.
+                       // there are few scenarios in which these will fail...
+                       bool                            
SuggestCompositingMode(performance_mode,
+                                                                               
composite_mode = NORMAL_COMPOSITE);
+
+                       bool                            
RequireCompositingMode(performance_mode,
+                                                                               
composite_mode = NORMAL_COMPOSITE);
+                       
+};
+
+
+class CompositeEngine : public HWInterfaceListener{
+public:
+       explicit                                        CompositeEngine();
+                                                               
~CompositeEngine();     // no use for a vtable...
+
+                       // without a HWInterface we can't push out to the 
hardware
+                       bool                            
SetHWInterface(HWInterface* interface);
+                       HWInterface*            GetHWInterface()        const;
+                       
+                       bool                            IsCompositingEnabled()  
const;  
+                       status_t                        
SetCompositingEnabled(bool enable);
+                                                               // synchronous
+               
+                       size_t                          TotalMemoryUsage();
+                       size_t                          
LimitMemoryUsage(size_t);
+                               // returns actual limit approved
+                       
+                       size_t                          MemoryLimit()   const;
+                                       
+               // Clients
+                       status_t                        
AttachClient(CompositeEngineClient*
+                                                                               
listener);
+                       status_t                        
DetachClient(CompositeEngineClient*
+                                                                               
listener);
+
+                       uint8                           CurrentFPS()    const;
+                       uint8                           MaxFPS()                
const;
+                       
+                       performance_mode        PerformanceMode()       const;
+                       bool                            
RequirePerformanceMode(performance_mode mode);
+                               // if we can't get the mode (or higher) we 
don't try to elevate
+                               // we simply return false and remain in 
whatever mode we were
+                               // already in.
+                       
+                       bool                            
SuggestPerformanceMode(performance_mode mode);
+                               // SuggestPerformanceMode() will do its best to 
elevate to as
+                               // close to the requested mode as possible.  
The reasons for
+                               // the mode to not elevate are as follows:
+                                       // Low memory, slow front buffer 
access, system limits,
+                                       // power saving mode, etc...
+                       
+                       
+                       // back-buffer operations
+                       void                            Copy(BRect src, BRect 
dest);
+                       void                            Move(BRect src, BRect 
dest);
+                                                                       // 
updates dirty areas as well
+                       
+                       void                            Invalidate(BRect rect);
+                       void                            Fill(BRect rect, 
rgb_color);
+                       
+                       UpdateQueue*            GetUpdateQueue() const;
+                               // if compositing is enabled we return 
CompositeUpdateQueue,
+                               // otherwise we will return HWUpdateQueue
+                       
+                       void                            SetDirty(BRegion& 
region);
+                       void                            SetDirty(Window* 
window, BRegion& region);
+                       
+                       ServerBitmap*           GetBitmap(BRect rect);
+
+                       // color_space must equal B_RGBA32
+                       bool                            DrawBitmap(BRect, 
ServerBitmap*);
+                       bool                            DrawBitmap(BPoint, 
ServerBitmap*);
+                       
+                       void                            DrawWindow(Window*);
+                       
+                       void                            
SetFullScreenWindow(Window*);
+                               // disables background updates...
+                       
+                       // full-screen fading (synchronous)
+                       void                            FadeOut();
+                       void                            FadeIn();
+                       
+                       void                            SetGreyscale(bool);
+                       bool                            IsGreyscale()   const;
+                       
+                       
+                       
+private:
+       static  int32                           _MasterControlThread(void*);
+       static  int32                           _SlaveRenderThread(void*);
+       static  int32                           _BackToFrontThread(void*);
+       
+                       BRect                           _NextUpdateRect(bool&);
+                       uint8                           
_NextUpdateBatchWeight();
+                       void                            _PushToFront();
+                       void                            
_SetPerformanceMode(performance_mode);
+                       
+                       BLocker                         fClientsLock,
+                                                               fModeSwitchLock,
+                                                               fMasterLock;
+                       
+                       BObjectList<CompositeEngineClient>
+                                                               fClients;
+                       
+                       uint8                           fFrames_Max,
+                                                               fFrames_Average,
+                                                               fFrames_Target,
+                                                               
fUpdates_PendingPriority;
+                       
+                       bigtime_t                       fUpdate_DesiredInterval,
+                                                               
fUpdate_NextTime,
+                                                               
fEngine_InstantiatedTime,
+                                                               
fEngine_EnabledTime;
+                       
+                       performance_mode        fPerformanceMode,
+                                                               
fPerformanceMode_Last;
+                       
+                       bool                            fCompositingEnabled     
        : 1;
+                                                               
+};
+
+extern "C" CompositeEngine*            gCompositeEngine;
+
+#endif // COMPOSITING_ENGINE_H
+
diff --git a/src/servers/app/drawing/compositing/CompositeUpdateQueue.cpp 
b/src/servers/app/drawing/compositing/CompositeUpdateQueue.cpp
new file mode 100644
index 0000000..cabc9ea
--- /dev/null
+++ b/src/servers/app/drawing/compositing/CompositeUpdateQueue.cpp
@@ -0,0 +1,4 @@
+#include "CompositeUpdateQueue.h"
+
+
+
diff --git a/src/servers/app/drawing/compositing/CompositeUpdateQueue.h 
b/src/servers/app/drawing/compositing/CompositeUpdateQueue.h
new file mode 100644
index 0000000..155e271
--- /dev/null
+++ b/src/servers/app/drawing/compositing/CompositeUpdateQueue.h
@@ -0,0 +1,47 @@
+#ifndef COMPOSITE_UPDATE_QUEUE_H
+#define COMPOSITE_UPDATE_QUEUE_H
+
+/*
+       CompositeUpdateQueue
+               Accumulates all dirty areas of the back-buffer for they
+               can be copied to the front buffer on demand.
+               
+               Unlike HWUpdateQueue, the code for the copy is not here -
+               it is in the CompositeEngine.
+*/
+
+#include "CompositeEngine.h"
+#include "UpdateQueue.h"
+
+class CompositeUpdateQueue : public UpdateQueue, public CompositeEngineClient{
+ public:
+       explicit                                        CompositeUpdateQueue();
+       virtual                                         ~CompositeUpdateQueue();
+       
+                       void                            CompositingEnabling();
+                       void                            CompositingDisabling();
+                       
+                       void                            
CompositingEnabled(bool);
+                       void                            
CompositingChanged(performance_mode, 
+                                                                               
                        composite_mode);
+
+                       // ALL functions lock, unless stated...
+                       
+                       // number of rects in the region...
+                       int32                           CountPendingUpdates();  
                                                        
+                       
+                       /*
+                               PendingUpdateArea() calculates the pixel area 
which the
+                               pending updates cover.  By area, I mean width * 
height...
+                               
+                               The stopMath parameter tells us to stop 
accumulating once
+                               we hit that particular area of coveragee.  If 
we hit that
+                               area, we return stopMath (even if we calculated 
to higher).
+                       */
+                       int32                           PendingUpdateArea(int32 
stopMath = 10000);
+                       
+                       BRegion*                        UpdateRegion();
+};
+
+
+#endif // COMPOSITE_UPDATE_QUEUE_H
diff --git a/src/servers/app/drawing/compositing/CompositingPerfmon.h 
b/src/servers/app/drawing/compositing/CompositingPerfmon.h
new file mode 100644
index 0000000..7056283
--- /dev/null
+++ b/src/servers/app/drawing/compositing/CompositingPerfmon.h
@@ -0,0 +1,47 @@
+#ifndef COMPOSITING_PERFORMANCE_MONITOR_H
+#define COMPOSITING_PERFORMANCE_MONITOR_H
+
+
+/*
+       CompositingPerfmon is informed of every performance-related bit of
+       information the CompositeEngine generates.
+       
+       Very simple at this point.
+*/
+
+class CompositingPerfmon{
+ public:
+                                                       CompositingPerfmon(bool 
enable = false);
+                                                       ~CompositingPerfmon();
+       
+                       bool                    MonitoringEnabled()     const;
+                       
+                       // determines frame rate & avg cost.
+                       void                    BackToFrontBegins       ();
+                       void                    BackToFrontEnds         ();
+                       
+                       // triple buffering
+                       void                    BackBufferSwapBegins();
+                       void                    BackBufferSwapEnds      ();
+                       
+                       // only on full-window re-compositing
+                       void                    RenderWindowBegins      
(Window*);
+                       void                    RenderWindowEnds        
(Window*);
+
+                       
+                       // enabling / disabling compositing...
+                       void                    DisableBegins           ();
+                       void                    DisableEnds                     
();
+                       
+                       void                    EnableBegins            ();
+                       void                    EnableEnds                      
();
+                       
+                       
+                       
+                       
+
+};
+
+
+#endif
+
diff --git a/src/servers/app/drawing/compositing/Jamfile 
b/src/servers/app/drawing/compositing/Jamfile
new file mode 100644
index 0000000..8751fc3
--- /dev/null
+++ b/src/servers/app/drawing/compositing/Jamfile
@@ -0,0 +1,18 @@
+SubDir HAIKU_TOP src servers app drawing compositing ;
+
+UseLibraryHeaders agg ;
+UsePrivateHeaders app graphics interface kernel shared ;
+UsePrivateHeaders [ FDirName graphics common ] ;
+UsePrivateSystemHeaders ;
+
+UseHeaders [ FDirName $(HAIKU_TOP) src servers app ] ;
+UseHeaders [ FDirName $(HAIKU_TOP) src servers app font ] ;
+UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
+UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;
+UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter 
drawing_modes ] ;
+UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter 
font_support ] ;
+UseHeaders $(HAIKU_FREETYPE_HEADERS) : true ;
+
+StaticLibrary libasdrawing.a :
+       CompositeUpdateQueue.cpp
+;

############################################################################

Commit:      58fcae348665fa57b49ba0f675d857218ed7382d

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Sat Mar 24 00:15:18 2012 UTC

Finally a working man's commit...

Much future planning (immediate future...), app_server communication protocol 
setup started, fixed a few things, changed some more, yadda yadda.

All compiles, but will not link.  That is intentional (lets me know where I am 
going next in case I forget to add a note to my TODO).

----------------------------------------------------------------------------

diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h
index 03a63e1..ae3f6d0 100644
--- a/headers/os/interface/Window.h
+++ b/headers/os/interface/Window.h
@@ -240,6 +240,11 @@ public:
                        bool                            IsModal() const;
                        bool                            IsFloating() const;
 
+       virtual void                            SetDrawingMode(drawing_mode 
mode);
+                       drawing_mode            DrawingMode() const;
+                       
+                       bool                            IsCompositingEnabled()  
const;
+
                        status_t                        
SetWindowAlignment(window_alignment mode,
                                                                        int32 
h, int32 hOffset = 0,
                                                                        int32 
width = 0, int32 widthOffset = 0,
@@ -352,7 +357,10 @@ private:
 
                        void                            
_GetDecoratorSize(float* _borderWidth,
                                                                        float* 
_tabHeight) const;
-
+protected:
+                       bool                            
_SetFullscreenCompositeModeEnabled(bool);
+                       bigtime_t                       _DimEffect_ByHalf();
+                       bigtime_t                       _DimEffect_ToNormal();
 private:
                        char*                           fTitle;
                        int32                           _unused0;
diff --git a/headers/private/app/CompositingPrivate.h 
b/headers/private/app/CompositingPrivate.h
new file mode 100644
index 0000000..ff196e4
--- /dev/null
+++ b/headers/private/app/CompositingPrivate.h
@@ -0,0 +1,160 @@
+#ifndef COMPOSITING_PRIVATE_H
+#define COMPOSITING_PRIVATE_H
+
+#include <OS.h>
+#include <String.h>
+
+class BWindow;
+
+namespace BPrivate{
+
+/*
+       performance_mode determines the rate at which we will update changes
+       in the back-buffer into the front-buffer.
+       We batch updates together and change the performance mode based on the
+       amount of changes made, the area covered - along with app-requested 
+       performance modes (new API) or ServerWindow requests based on user
+       action (window resize/move, typing, etc...)
+       Just becauuse we are in, say, FULL_PERFORMANCE_MODE does not mean we
+       will actually be operating at a full 60 fps, that is just the reference
+       update interval (1/60th of a second [minus some time for overhead])     
+*/
+enum performance_mode{
+               STOP_PERFORMANCE_MODE = 0,      //   0  fps (screen off)
+               SLOW_PERFORMANCE_MODE = 5,      // <= 5 fps (sitting at the 
desktop)
+               MILD_PERFORMANCE_MODE = 15,     // < 15 fps (normal GUIs, low 
motion)
+               HIGH_PERFORMANCE_MODE = 30,     // < 30 fps (videos, moderate 
motion)
+               FULL_PERFORMANCE_MODE = 60,     // ~ 60 fps (animations, moving 
video)
+               SYNC_PERFORMANCE_MODE = 120,// @ refresh rate - up to 120hz
+               WILD_PERFORMANCE_MODE = 1000// max power! - up to 1000fps...
+};
+
+enum composite_mode{
+               NORMAL_COMPOSITE = 0//, // CPU[s] do[es] the work
+       //      ACCEL_COMPOSITE,        // GPU accelerated
+       //      MIXED_COMPOSITE,        // CPU does some, GPU does some
+       //      XGPUS_COMPOSITE,        // multiple GPUs for compositing
+       //      XHEAD_COMPOSITE         // treat monitors separately -
+                                                               // one 
workspace per monitor ;-)
+};
+
+/*
+       composite_client_type
+       
+       It is often useful for the CompositeEngine to know what type of client
+       is denying or making a request so as to react properly.
+       
+       Basically, if a Desktop requests STOP_PERFORMANCE_MODE, that means the
+       monitor has gone to black (or is going to sleep).  If a Window asks, we
+       will outright deny it.  If a workspace asks, and we are in 
XHEAD_COMPOSITE,
+       then we stop updates for the screen for that workspace, only increasing
+       when the workspace permits us.
+       
+       This allows us to not touch the code too much in the future.
+               
+       A CompositeEngineClient can identify itself as being of one of types
+       as follows:
+*/
+enum composite_client_type{
+       ANONYMOUS_COMPOSITE_CLIENT      = 0,
+       DESKTOP_COMPOSITE_CLIENT,
+       DESKTOPWINDOW_COMPOSITE_CLIENT,
+       WORKSPACE_COMPOSITE_CLIENT,
+       WINDOW_COMPOSITE_CLIENT,
+       SERVERWINDOW_COMPOSITE_CLIENT,
+       DIRECTWINDOW_COMPOSITE_CLIENT,
+       UPDATEQUEUE_COMPOSITE_CLIENT,
+       FULLSCREEN_COMPOSITE_CLIENT     // screensaver, game, etc...
+};
+
+
+/*
+typedef struct CompositingStatus{
+       bool                                    enabled;
+       bigtime_t                               timeEnabled;
+       performance_mode                performanceMode;
+       composite_mode                  compositingMode;
+       int32                                   frameRate,
+                                                       averagesUpdates;        
// per refresh
+       
+       size_t                                  memoryLimit,
+                                                       memoryUsageEstimate;
+       
+       bool                                    mouseIsOverlay,
+                                                       shadowsEnabled,
+                                                       dimmingEnabled,
+                                                       fullscreenActive;
+       
+       BString                                 mouseOverlay;   // by name
+};
+*/
+
+uint8                          
compositingPerfLevelForPerfMode(performance_mode);
+performance_mode       compositingPerfModeForPerfLevel(uint8);
+int32                          compositingRateForPerfMode(performance_mode);
+       
+// user-side onlly - don't use from within app_server
+bool                           getCompositingEnabled();
+bool                           setCompositingEnabled(bool);
+
+bool                           setCompositingMode(composite_mode);
+composite_mode         getCompositingMode();
+
+performance_mode       getCompositingPerformance();
+status_t                       setCompositingPerformance(performance_mode);
+
+int32                          getCompositingFPS();
+
+size_t                         getCompositingMemoryLimit();
+size_t                         setCompositingMemoryLimit(size_t);
+       // returns new limit - you may never get an exact
+       // match... minimum is about 1.5*frame buffer size
+
+size_t                         getCompositingMemoryUsageEstimate();
+size_t                         getCompositingMemoryUsage();
+               // avoid calling this, it forcefully calculates the
+               // actual usage.
+
+//CompositingStatus    getCompositingStatus();
+               // this (will be) a heavy call, use only when you need
+               // all the information at once
+       
+BString                                getCompositingMouseOverlay();
+bool                           setCompositingMouseOverlay(const BString&);
+       // by name, not path
+
+bool                           getCompositingFullscreenMode();
+status_t                       setCompositingFullscreenMode(BWindow*, bool);
+       // set a window to be treated as full-screen
+               // ALL other updates cease until the window is destroyed
+               // or this is called again, with false to disable the mode.
+
+
+// TODO: consider moving built-in effects to its own place...
+
+bool                           getShadowEffectsEnabled();
+bool                           setShadowEffectsEnabled(bool);
+/*
+BMessage*                      getShadowEffectsConfig();
+bool                           setShadowEffectsConfig();
+*/
+// returns time until effect should be complete
+bigtime_t                      dimEffect_ScreenByHalf();
+bigtime_t                      dimEffect_ScreenToBlack();
+bigtime_t                      dimEffect_ScreenToNormal();
+
+// BWindow has its own internal method we access
+bigtime_t                      dimEffect_WindowByHalf(BWindow*);
+bigtime_t                      dimEffect_WindowToNormal(BWindow*);
+/*
+bool                           setEffect_Addon(BString);
+BString                                getEffect_Addon();
+*/
+       
+};
+
+
+
+
+#endif
+
diff --git a/headers/private/app/ServerProtocol.h 
b/headers/private/app/ServerProtocol.h
index ef7c439..946d457 100644
--- a/headers/private/app/ServerProtocol.h
+++ b/headers/private/app/ServerProtocol.h
@@ -112,6 +112,41 @@ enum {
        AS_SET_SIZE_LIMITS,
        AS_ACTIVATE_WINDOW,
        AS_IS_FRONT_WINDOW,
+       AS_SET_DRAWING_MODE,
+       AS_GET_DRAWING_MODE,
+       
+       // Compositing definitions
+       AS_SET_COMPOSITING_ENABLED,
+       AS_GET_COMPOSITING_ENABLED,
+       AS_SET_COMPOSITING_MODE,
+       AS_GET_COMPOSITING_MODE,
+       AS_SET_COMPOSITING_PERFORMANCE,
+       AS_GET_COMPOSITING_PERFORMANCE,
+       AS_GET_COMPOSITING_FPS,
+       AS_SET_COMPOSITING_MEMLIMT,
+       AS_GET_COMPOSITING_MEMLIMT,
+       AS_GET_COMPOSITING_MEMUSAGE_ESTIMATE,
+       AS_GET_COMPOSITING_MEMUSAGE,
+       AS_GET_COMPOSITING_STATUS,
+       AS_SET_COMPOSITING_MOUSE_OVERLAY,
+       AS_GET_COMPOSITING_MOUSE_OVERLAY,
+       AS_GET_COMPOSITING_DIMMING_ENABLED,
+       AS_SET_COMPOSITING_DIMMING_ENABLED,
+       AS_GET_COMPOSITING_FULLSCREEN_MODE,
+       AS_SET_COMPOSITING_FULLSCREEN_MODE,
+       
+       // built-in effects
+       AS_SET_EFFECT_SHADOWS_ENABLED,
+       AS_GET_EFFECT_SHADOWS_ENABLED,
+       AS_SET_EFFECT_SHADOWS_CONFIG,
+       AS_GET_EFFECT_SHADOWS_CONFIG,
+       AS_DIM_EFFECT_SCREEN_BY_HALF,
+       AS_DIM_EFFECT_SCREEN_TO_BLACK,
+       AS_DIM_EFFECT_SCREEN_TO_NORMAL,
+       AS_DIM_EFFECT_WINDOW_BY_HALF,
+       AS_DIM_EFFECT_WINDOW_TO_NORMAL,
+       AS_SET_EFFECT_ADD_ON,
+       AS_GET_EFFECT_ADD_ON,
 
        // BPicture definitions
        AS_CREATE_PICTURE,
diff --git a/src/kits/app/CompositingPrivate.cpp 
b/src/kits/app/CompositingPrivate.cpp
new file mode 100644
index 0000000..627d1b4
--- /dev/null
+++ b/src/kits/app/CompositingPrivate.cpp
@@ -0,0 +1,283 @@
+#include <AppServerLink.h>
+#include <ServerProtocol.h>
+#include <String.h>
+#include <OS.h>
+
+// not really fond of this... but need it... for now
+#define protected public
+#      include <Window.h>
+#undef protected
+
+#include "CompositingPrivate.h"
+
+
+namespace BPrivate{
+
+
+int32 compositingRateForPerfMode(performance_mode mode)
+{
+       return (int32)mode;     
+}
+
+uint8  compositingPerfLevelForPerfMode(performance_mode mode)
+{
+       switch(mode){
+               case STOP_PERFORMANCE_MODE:
+                       return 0;
+               case SLOW_PERFORMANCE_MODE:
+                       return 1;
+               case MILD_PERFORMANCE_MODE:
+                       return 2;
+               case HIGH_PERFORMANCE_MODE:
+                       return 3;
+               case FULL_PERFORMANCE_MODE:
+                       return 4;
+               case SYNC_PERFORMANCE_MODE:
+                       return 5;
+               case WILD_PERFORMANCE_MODE:
+                       return 6;
+       };
+
+       return 3;
+}
+
+performance_mode       compositingPerfModeForPerfLevel(uint8 level)
+{
+       switch(level){
+               case 0: return STOP_PERFORMANCE_MODE;
+               case 1: return SLOW_PERFORMANCE_MODE;
+               case 2: return MILD_PERFORMANCE_MODE;
+               case 3: return HIGH_PERFORMANCE_MODE;
+               case 4: return FULL_PERFORMANCE_MODE;
+               case 5: return SYNC_PERFORMANCE_MODE;
+               case 6: return WILD_PERFORMANCE_MODE;
+       };
+               // never will get here...
+       return HIGH_PERFORMANCE_MODE;
+}
+
+
+performance_mode       getCompositingPerformance()
+{
+       int32 perfLevel;
+       AppServerLink link;
+       link.StartMessage(AS_GET_COMPOSITING_PERFORMANCE);
+
+       int32 code;
+       if (link.FlushWithReply(code) == B_OK) {
+               link.Read<int32>(&perfLevel);
+       }
+       
+       return compositingPerfModeForPerfLevel(perfLevel);
+}
+       
+       
+       
+bool           getCompositingEnabled()
+{
+       bool enabled = false;
+       BPrivate::AppServerLink link;
+       link.StartMessage(AS_GET_COMPOSITING_ENABLED);
+
+       int32 code;
+       if (link.FlushWithReply(code) == B_OK) {
+               link.Read<bool>(&enabled);
+       }
+
+       return enabled;
+}
+
+bool           setCompositingEnabled(bool enable)
+{
+       BPrivate::AppServerLink link;
+       link.StartMessage(AS_SET_COMPOSITING_ENABLED);
+       link.Attach<bool>(enable);
+       link.Flush();
+       return getCompositingEnabled();
+}
+
+
+
+bool           setCompositingMode(composite_mode mode)
+{      // noop
+       return true;    
+}
+
+composite_mode getCompositingMode()
+{
+       return NORMAL_COMPOSITE;        
+}
+
+
+status_t                       setCompositingPerformance(performance_mode mode)
+{
+       BPrivate::AppServerLink link;
+       link.StartMessage(AS_SET_COMPOSITING_PERFORMANCE);
+       link.Attach<uint8>(compositingPerfLevelForPerfMode(mode));
+       link.Flush();
+       return B_OK;    // no error support yet...
+}
+
+
+
+int32                          getCompositingFPS()
+{
+       BPrivate::AppServerLink link;
+       
+       int32 fps;
+       link.StartMessage(AS_GET_COMPOSITING_FPS);
+       int32 status = B_ERROR;
+       if (link.FlushWithReply(status) != B_OK || status != B_OK)
+               return -1;
+       link.Read<int32>(&fps);
+       return fps;
+}
+
+
+
+size_t                         getCompositingMemoryLimit()
+{
+       BPrivate::AppServerLink link;
+       
+       size_t limit;
+       link.StartMessage(AS_GET_COMPOSITING_MEMLIMT);
+       int32 status = B_ERROR;
+       if (link.FlushWithReply(status) != B_OK || status != B_OK)
+               return 0;       // just say no limit...
+       link.Read<size_t>(&limit);
+       return limit;
+}
+
+
+size_t                         setCompositingMemoryLimit(size_t limit)
+{
+       BPrivate::AppServerLink link;
+       link.StartMessage(AS_SET_COMPOSITING_MEMLIMT);
+       link.Attach<size_t>(limit);
+       link.Flush();
+
+       return getCompositingMemoryLimit();     
+}
+
+
+
+size_t                         getCompositingMemoryUsageEstimate()
+{
+       BPrivate::AppServerLink link;
+       
+       size_t usage;
+       link.StartMessage(AS_GET_COMPOSITING_MEMUSAGE_ESTIMATE);
+       int32 status = B_ERROR;
+       if (link.FlushWithReply(status) != B_OK || status != B_OK)
+               return 0;       // just say no usage...
+       link.Read<size_t>(&usage);
+       return usage;
+}
+
+size_t                         getCompositingMemoryUsage()
+{      // may look almost identical... but MUCH more work is done when 
called...
+       BPrivate::AppServerLink link;
+       
+       size_t usage;
+       link.StartMessage(AS_GET_COMPOSITING_MEMUSAGE);
+       int32 status = B_ERROR;
+       if (link.FlushWithReply(status) != B_OK || status != B_OK)
+               return 0;       // just say no usage...
+       link.Read<size_t>(&usage);
+       return usage;   
+}
+
+
+
+BString                                getCompositingMouseOverlay()
+{
+       return "";      
+}
+
+bool                           setCompositingMouseOverlay(const BString& 
overlay)
+{
+       return false;
+}
+
+
+// #pragma mark Builtin Effects
+
+
+bool                           getShadowEffectsEnabled()
+{
+       bool enabled = false;
+       BPrivate::AppServerLink link;
+       link.StartMessage(AS_GET_EFFECT_SHADOWS_ENABLED);
+
+       int32 code;
+       if (link.FlushWithReply(code) == B_OK) {
+               link.Read<bool>(&enabled);
+       }
+
+       return enabled;
+       
+}
+
+bool                           setShadowEffectsEnabled(bool enable)
+{
+       BPrivate::AppServerLink link;
+       link.StartMessage(AS_SET_EFFECT_SHADOWS_ENABLED);
+       link.Attach<bool>(enable);
+       link.Flush();
+       
+       return getShadowEffectsEnabled();       
+}
+
+
+
+bigtime_t                      dimEffect_ScreenByHalf()
+{
+       BPrivate::AppServerLink link;
+       bigtime_t time = 0;
+       link.StartMessage(AS_DIM_EFFECT_SCREEN_BY_HALF);
+       int32 code;
+       
+       if (link.FlushWithReply(code) == B_OK)
+               link.Read<bigtime_t>(&time);
+       
+       return time;
+}
+
+bigtime_t                      dimEffect_ScreenToBlack()
+{
+       BPrivate::AppServerLink link;
+       bigtime_t time = 0;
+       link.StartMessage(AS_DIM_EFFECT_SCREEN_TO_BLACK);
+       int32 code;
+       
+       if (link.FlushWithReply(code) == B_OK)
+               link.Read<bigtime_t>(&time);
+       
+       return time;
+}
+
+bigtime_t                      dimEffect_ScreenToNormal()
+{
+       BPrivate::AppServerLink link;
+       bigtime_t time = 0;
+       link.StartMessage(AS_DIM_EFFECT_SCREEN_TO_NORMAL);
+       int32 code;
+       
+       if (link.FlushWithReply(code) == B_OK)
+               link.Read<bigtime_t>(&time);
+       
+       return time;
+}
+
+bigtime_t                      dimEffect_WindowByHalf(BWindow* window)
+{
+       return window->_DimEffect_ByHalf();
+}
+
+bigtime_t                      dimEffect_WindowToNormal(BWindow* window)
+{
+       return window->_DimEffect_ToNormal();
+}
+
+
+};     // end namespace BPrivate
diff --git a/src/kits/app/Jamfile b/src/kits/app/Jamfile
index 1f01a00..dd03249 100644
--- a/src/kits/app/Jamfile
+++ b/src/kits/app/Jamfile
@@ -28,6 +28,7 @@ MergeObject <libbe>app_kit.o :
        Application.cpp
        AppMisc.cpp
        AppServerLink.cpp
+       CompositingPrivate.cpp
        Cursor.cpp
        Clipboard.cpp
        DesktopLink.cpp
diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp
index 80729cd..43a3ea6 100644
--- a/src/kits/interface/Window.cpp
+++ b/src/kits/interface/Window.cpp
@@ -2117,6 +2117,50 @@ BWindow::Frame() const
 }
 
 
+void
+BWindow::SetDrawingMode(drawing_mode mode)
+{      // if compositing is enabled this has an effect
+       // otherwise it really has no effect (at this point)
+       
+       if (Lock()) {
+               fLink->StartMessage(AS_SET_DRAWING_MODE);
+               fLink->Attach<int8>((int8)mode);
+               fLink->Flush();
+               Unlock();
+       }
+       
+}
+
+
+drawing_mode
+BWindow::DrawingMode() const
+{
+       int8 drawingMode = (int8) B_OP_OVER;
+
+       fLink->StartMessage(AS_GET_DRAWING_MODE);
+
+       int32 code;
+       if (fLink->FlushWithReply(code) == B_OK && code == B_OK) {
+               fLink->Read<int8>(&drawingMode);                
+       }
+       return (drawing_mode)drawingMode;
+}
+
+
+bool
+BWindow::IsCompositingEnabled()        const
+{      // we have a link, no need to use utilty functions...
+       bool enabled = false;
+       fLink->StartMessage(AS_GET_COMPOSITING_ENABLED);
+
+       int32 code;
+       if (fLink->FlushWithReply(code) == B_OK && code == B_OK) {
+               fLink->Read<bool>(&enabled);
+       }
+       return enabled;
+}
+
+
 BRect
 BWindow::DecoratorFrame() const
 {
@@ -4059,6 +4103,73 @@ BWindow::_GetDecoratorSize(float* _borderWidth, float* 
_tabHeight) const
 }
 
 
+/*
+       _SetFullscreenCompositeModeEnabled:
+               Tells CompositeEngine to treat this window as if it
+               were the only thing visible on screen.
+               
+       All other updates cease. If we are in B_OP_ALPHA mode the
+       current screen buffer is cached (with this window 'hidden')
+       and is used as the backdrop.
+
+       Further, in the future, updates application's make to their
+       windows will be discarded while this mode is held and when
+       the mode is released, each visible window will be asked to
+       redraw their contents.
+       
+       Screensavers, full-screen games, and full-screen video should
+       all invoke this for maximum performance, and disable this once
+       done.
+       
+       This is why it is a protected member, rather than private.
+       
+       TODO: consider a new name and improve visibility???
+*/
+bool
+BWindow::_SetFullscreenCompositeModeEnabled(bool enable)
+{
+       fLink->StartMessage(AS_SET_COMPOSITING_FULLSCREEN_MODE);
+       fLink->Attach<bool>(enable);
+       fLink->Flush();
+       
+       bool value = false;
+               // TODO: work out two-way communication details... sure
+               // it already works... just don't know how - yet ;-)
+       return value;
+}
+
+
+// These functions will normally be called externally.
+bigtime_t      // window will be dimmed with an overlay
+BWindow::_DimEffect_ByHalf()
+{      // please note: dimmed windows do not have control input locked!
+       // it is a visual indicator only (unlike screen dimming)
+       fLink->StartMessage(AS_DIM_EFFECT_WINDOW_BY_HALF);
+       bigtime_t time = 0;
+       
+       int32 code;
+       if (fLink->FlushWithReply(code) == B_OK)
+               fLink->Read<bigtime_t>(&time);
+
+       return time;
+}
+
+
+bigtime_t      // dimming level will fade away
+BWindow::_DimEffect_ToNormal()
+{      // if not dimmed, this is all for not ;-)
+       fLink->StartMessage(AS_DIM_EFFECT_WINDOW_TO_NORMAL);
+       bigtime_t time = 0;
+       
+       int32 code;
+       if (fLink->FlushWithReply(code) == B_OK)
+               fLink->Read<bigtime_t>(&time);
+               
+       return time;
+}
+
+
+
 //     #pragma mark - C++ binary compatibility kludge
 
 
diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile
index f31ebbb..0494ac0 100644
--- a/src/servers/app/Jamfile
+++ b/src/servers/app/Jamfile
@@ -4,6 +4,7 @@ UseLibraryHeaders agg ;
 UsePrivateHeaders app graphics input interface kernel shared storage support ;
 
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
+UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing compositing ] ;
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app stackandtile ] ;
 
diff --git a/src/servers/app/ProfileMessageSupport.cpp 
b/src/servers/app/ProfileMessageSupport.cpp
index 5472f04..7ef75bd 100644
--- a/src/servers/app/ProfileMessageSupport.cpp
+++ b/src/servers/app/ProfileMessageSupport.cpp
@@ -91,6 +91,42 @@ string_for_message_code(uint32 code, BString& string)
                CODE(AS_SET_SIZE_LIMITS);
                CODE(AS_ACTIVATE_WINDOW);
                CODE(AS_IS_FRONT_WINDOW);
+               CODE(AS_SET_DRAWING_MODE);
+               CODE(AS_GET_DRAWING_MODE);
+       
+       // Compositing definitions
+               CODE(AS_SET_COMPOSITING_ENABLED);
+               CODE(AS_GET_COMPOSITING_ENABLED);
+               CODE(AS_SET_COMPOSITING_MODE);
+               CODE(AS_GET_COMPOSITING_MODE);
+               CODE(AS_SET_COMPOSITING_PERFORMANCE);
+               CODE(AS_GET_COMPOSITING_PERFORMANCE);
+               CODE(AS_GET_COMPOSITING_FPS);
+               CODE(AS_SET_COMPOSITING_MEMLIMT);
+               CODE(AS_GET_COMPOSITING_MEMLIMT);
+               CODE(AS_GET_COMPOSITING_MEMUSAGE_ESTIMATE);
+               CODE(AS_GET_COMPOSITING_MEMUSAGE);
+               CODE(AS_GET_COMPOSITING_STATUS);
+               CODE(AS_SET_COMPOSITING_MOUSE_OVERLAY);
+               CODE(AS_GET_COMPOSITING_MOUSE_OVERLAY);
+               CODE(AS_GET_COMPOSITING_DIMMING_ENABLED);
+               CODE(AS_SET_COMPOSITING_DIMMING_ENABLED);
+               CODE(AS_GET_COMPOSITING_FULLSCREEN_MODE);
+               CODE(AS_SET_COMPOSITING_FULLSCREEN_MODE);
+       
+       // built-in effects
+               CODE(AS_SET_EFFECT_SHADOWS_ENABLED);
+               CODE(AS_GET_EFFECT_SHADOWS_ENABLED);
+               CODE(AS_SET_EFFECT_SHADOWS_CONFIG);
+               CODE(AS_GET_EFFECT_SHADOWS_CONFIG);
+               CODE(AS_DIM_EFFECT_SCREEN_BY_HALF);
+               CODE(AS_DIM_EFFECT_SCREEN_TO_BLACK);
+               CODE(AS_DIM_EFFECT_SCREEN_TO_NORMAL);
+               CODE(AS_DIM_EFFECT_WINDOW_BY_HALF);
+               CODE(AS_DIM_EFFECT_WINDOW_TO_NORMAL);
+               CODE(AS_SET_EFFECT_ADD_ON);
+               CODE(AS_GET_EFFECT_ADD_ON);
+
 
                // BPicture definitions
                CODE(AS_CREATE_PICTURE);
diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp
index 8ffea24..34d0c3e 100644
--- a/src/servers/app/ServerWindow.cpp
+++ b/src/servers/app/ServerWindow.cpp
@@ -53,6 +53,7 @@
 
 #include "AppServer.h"
 #include "AutoDeleter.h"
+#include "CompositeEngine.h"
 #include "Desktop.h"
 #include "DirectWindowInfo.h"
 #include "DrawingEngine.h"
@@ -844,7 +845,55 @@ ServerWindow::_DispatchMessage(int32 code, 
BPrivate::LinkReceiver& link)
                        fLink.Flush();
                        break;
                }
-
+               case AS_SET_DRAWING_MODE:
+               {       DTRACE(("ServerWindow %s: Message 
AS_SET_DRAWING_MODE\n", Title()));
+                       int8 newMode = (int8)fWindow->DrawingMode();
+                       
+                       if (link.Read<int8>(&newMode) == B_OK)
+                               fWindow->SetDrawingMode((drawing_mode)newMode);
+                       
+                       break;
+               }
+               case AS_GET_DRAWING_MODE:
+               {
+                       DTRACE(("ServerWindow %s: Message 
AS_GET_DRAWING_MODE\n", Title()));
+                       fLink.StartMessage(B_OK);
+                       fLink.Attach<int8>((int8)fWindow->DrawingMode());
+                       fLink.Flush();
+                       break;
+               }
+               case AS_SET_COMPOSITING_FULLSCREEN_MODE:
+               {
+                       DTRACE((
+                               "ServerWindow %s: Message 
AS_SET_COMPOSITING_FULLSCREEN_MODE\n",
+                                        Title()));
+                       bool enable;
+                       link.Read<bool>(&enable);
+                       fLink.StartMessage(B_OK);
+                       fLink.Attach<bool>(
+                               gCompositeEngine->SetToFullscreenMode(fWindow, 
enable));
+                               
+                       fLink.Flush();
+                       break;                  
+               }               
+               case AS_DIM_EFFECT_WINDOW_BY_HALF:
+               {
+                       DTRACE(("ServerWindow %s: Message 
AS_DIM_EFFECT_WINDOW_BY_HALF\n",
+                                        Title()));
+                       fLink.StartMessage(B_OK);
+                       fLink.Attach<bigtime_t>(fWindow->DimEffect_ByHalf());
+                       fLink.Flush();
+                       break;                  
+               }
+               case AS_DIM_EFFECT_WINDOW_TO_NORMAL:
+               {
+                       DTRACE(("ServerWindow %s: Message 
AS_DIM_EFFECT_WINDOW_TO_NORMAL\n",
+                                        Title()));
+                       fLink.StartMessage(B_OK);
+                       fLink.Attach<bigtime_t>(fWindow->DimEffect_ToNormal());
+                       fLink.Flush();
+                       break;
+               }
                case AS_GET_WORKSPACES:
                {
                        DTRACE(("ServerWindow %s: Message AS_GET_WORKSPACES\n", 
Title()));
diff --git a/src/servers/app/Window.h b/src/servers/app/Window.h
index 887f2d8..328141f 100644
--- a/src/servers/app/Window.h
+++ b/src/servers/app/Window.h
@@ -306,6 +306,14 @@ public:
                        bool                            MoveToTopStackLayer();
                        bool                            
MoveToStackPosition(int32 index,
                                                                        bool 
isMoving);
+                       
+                       // Window Compositing methods.
+                       drawing_mode            DrawingMode()   const;
+                       void                            
SetDrawingMode(drawing_mode);
+                       
+                       bigtime_t                       DimEffect_ByHalf();
+                       bigtime_t                       DimEffect_ToNormal();
+                       
 protected:
                        void                            
_ShiftPartOfRegion(BRegion* region,
                                                                        
BRegion* regionToShift, int32 xOffset,
diff --git a/src/servers/app/drawing/compositing/CompositeEngine.cpp 
b/src/servers/app/drawing/compositing/CompositeEngine.cpp
new file mode 100644
index 0000000..43c5a75
--- /dev/null
+++ b/src/servers/app/drawing/compositing/CompositeEngine.cpp
@@ -0,0 +1,333 @@
+#include <Autolock.h>
+#include <CompositingPrivate.h>
+
+#include "CompositeEngine.h"
+
+// auto-instantiate
+CompositeEngine        *       gCompositeEngine = new CompositeEngine();
+
+
+/*
+       Be forewarned: we have five separate locks which interact
+       with each other.  And that doesn't count the objects we
+       have which have their own locks...
+       
+       Use BAutolock whenever possible!!  And make sure you are
+       choosing the right lock(s)!
+*/
+
+CompositeEngine::CompositeEngine()
+       :
+       fClientsLock("AppServer::CompositeEngine_Clients"),
+       fModeSwitchLock("AppServer::CompositeEngine_ModeSwitch"),
+       fMasterLock("AppServer::CompositeEngine_MasterControl"),
+       fBackToFrontLock("AppServer::CompositeEngine_BackToFront"),
+       fHardwareLock("AppServer::CompositeEngine_HardwareInterface"),
+       fFrames_Max(0),
+       fFrames_Target(60),
+       fUpdates_PendingPriority(255),
+       fUpdate_DesiredInterval(1000000/60),
+       fUpdate_NextTime(system_time() + 10000),
+       fEngine_InstantiatedTime(system_time()),
+       fEngine_EnabledTime(0),
+       fPerformanceMode(FULL_PERFORMANCE_MODE),
+       fPerformanceMode_Last(STOP_PERFORMANCE_MODE),
+       fCompositeMode(NORMAL_COMPOSITE),
+       fCompositingEnabled(false),     // ALWAYS default to off
+       fHardware(NULL)
+       {
+               // when we come to be very little is alive,
+               // don't expect any other part of app_server to
+               // be ready or instantiated - they may not be.
+       }
+
+
+CompositeEngine::~CompositeEngine()
+{      // we are NEVER to be destructed.
+       debugger("AppServer Horror\n"
+                       "CompositeEngine destroyed!\n"
+                       "But this should not be!");     // 8-)
+}
+
+
+// #pragma mark -
+
+bool
+CompositeEngine::SetHWInterface(HWInterface* interface)
+{      // we do not assum ownership of the HWInterface
+       BAutolock _(fHardwareLock);
+       if (interface != NULL)
+               fHardware = interface;
+       else
+               return false;
+               
+       return true;    
+}
+
+
+HWInterface*
+CompositeEngine::GetHWInterface() const
+{      BAutolock _(fHardwareLock);
+       return fHardware;       
+}
+
+
+bool
+CompositeEngine::IsCompositingEnabled() const
+{      // we need the lock because we want to return true
+       // if we are almost enabled...
+       BAutolock _(fModeSwitchLock);
+       return fCompositingEnabled;
+}
+
+
+status_t
+CompositeEngine::SetCompositingEnabled(bool enable)
+{
+       BAutolock _(fModeSwitchLock);   
+
+       status_t error = B_UNSUPPORTED;
+       
+       return error;   
+}
+
+
+// #pragma mark MemLimits
+
+size_t
+CompositeEngine::CalculateMemoryUsage()
+{      // must traverse window list and sum up buffer sizes
+       // as well as the back buffer
+       BAutolock _(fModeSwitchLock);
+
+       size_t total = 0;
+       
+       return total == 0 ? fEstimatedMemoryUsage : total;
+}
+
+
+size_t
+CompositeEngine::EstimateMemoryUsage() const
+{      // accuracy is not guaranteed - no need to lock
+       return fEstimatedMemoryUsage;
+}
+
+
+size_t
+CompositeEngine::FrameBufferSize()     const
+{      BAutolock _(fModeSwitchLock);
+       return fFrameBufferSize;        
+}
+
+
+size_t
+CompositeEngine::LimitMemoryUsage(size_t limit)
+{
+       if (limit < FrameBufferSize()){
+               limit = (size_t)(((float)FrameBufferSize()) * 1.5);
+       }       // room for frame buffer and a little more...
+               // this SHOULD cause windows to render directly to the
+               // back-buffer, in turn, at the expense of performance...
+               // basically we swap WindowBuffer for BackBuffer
+                       // those aren't the names (yet)...
+
+       
+       fMemoryLimit = limit;
+       
+       if (fEstimatedMemoryUsage < fMemoryLimit){
+               BAutolock _(fModeSwitchLock);
+               _EnforceMemoryLimit();
+       }
+       
+       return fMemoryLimit;
+}
+
+
+size_t
+CompositeEngine::MemoryLimit() const
+{      BAutolock _(fModeSwitchLock);
+       return fMemoryLimit;    
+}
+
+
+// #pragma mark Clients
+
+
+status_t
+CompositeEngine::AttachClient(CompositeEngineClient* client)
+{      if (client == NULL)
+               return B_BAD_VALUE;
+       
+       BAutolock _(fClientsLock);
+       
+       // are we already in the list?
+       
+       if (fClients.IndexOf(client) >= 0)
+               return B_BAD_INDEX;
+               
+       return fClients.AddItem(client) ? B_OK : B_ERROR;
+}
+
+
+status_t
+CompositeEngine::DetachClient(CompositeEngineClient* client)
+{      if (client == NULL)
+               return B_BAD_VALUE;
+       
+       BAutolock _(fClientsLock);
+       if (fClients.IndexOf(client) < 0)
+               return B_BAD_INDEX;
+       
+       return (fClients.RemoveItem(client, false)) ? B_OK : B_ERROR;
+}
+
+
+// #pragma mark Performance
+
+uint8
+CompositeEngine::CurrentFPS() const
+{
+       //return fPerfmon->FrontBuffer()->CompletionRate(1000000);
+       return 0;
+}
+
+
+performance_mode
+CompositeEngine::PerformanceMode() const
+{      BAutolock _(fModeSwitchLock);
+       return fPerformanceMode;
+}
+
+
+
+bool
+CompositeEngine::RequirePerformanceMode(performance_mode mode, 
+                                               CompositeEngineClient* client)
+{
+       return _SetPerformanceMode(mode, client, true, true);
+}
+
+
+
+bool
+CompositeEngine::SuggestPerformanceMode(performance_mode mode,
+                                                                       
CompositeEngineClient* client)
+{
+       return _SetPerformanceMode(mode, client, false, true);
+}
+
+
+#define PerfModeLevel(x)       compositingPerfLevelForPerfMode(x)
+#define PerfModeByLevel(x)     compositingPerfModeForPerfLevel(x)
+
+bool
+CompositeEngine::_SetPerformanceMode(performance_mode mode, 
+                                       CompositeEngineClient* client, bool 
force, bool lock)
+{
+       if (lock) BAutolock _(fClientsLock);
+       // verify client is attached:
+       if (fClients.IndexOf(client) < 0)       // not a client
+                       return false;
+       
+       if (lock) BAutolock _(fModeSwitchLock);
+       
+       // weed out unacceptable requests:
+       
+       if (mode == STOP_PERFORMANCE_MODE
+               && client->CompositeClientType() != DESKTOP_COMPOSITE_CLIENT)
+               return false;
+
+       if (mode == WILD_PERFORMANCE_MODE
+               && client->CompositeClientType() != DESKTOP_COMPOSITE_CLIENT)
+               return false;
+       
+       bool faster =  PerfModeLevel(mode) > PerfModeLevel(fPerformanceMode);
+       
+       // ask clients if the new mode is acceptable, weigh opinions
+       
+       int32 blockWeight = 0, clientWeight = 0;
+       
+       CompositeEngineClient * blockingClient = NULL;
+       
+       for (int32 i = 0; i < fClients.CountItems(); ++i){
+               if (fClients.ItemAt(i)->
+                               CompositingModeRequested(mode, fCompositeMode) 
== false){
+                       
+                       blockingClient = fClients.ItemAt(i);
+                       clientWeight = 
blockingClient->CompositeClientPriority() + 1;
+                       
+                       switch(blockingClient->CompositeClientType()){
+                               case ANONYMOUS_COMPOSITE_CLIENT:
+                                               break;
+                               case DESKTOP_COMPOSITE_CLIENT:                  
+                               case FULLSCREEN_COMPOSITE_CLIENT:
+                                               clientWeight *= faster ? 256 : 
128;
+                                               break;  // we like to get our 
way...
+                               case DESKTOPWINDOW_COMPOSITE_CLIENT:
+                                               clientWeight *= faster ? 64 : 
48;
+                                               break; // shouldn't be 
time-critical
+                               case WORKSPACE_COMPOSITE_CLIENT:
+                                               break;// special mode not yet 
supported
+                               case WINDOW_COMPOSITE_CLIENT:
+                                               clientWeight = faster ? 32 : 64;
+                                               break;  // prevent slow-downs, 
not speed-ups...
+                               case SERVERWINDOW_COMPOSITE_CLIENT:
+                               case DIRECTWINDOW_COMPOSITE_CLIENT:
+                               case UPDATEQUEUE_COMPOSITE_CLIENT:
+                                               break; // not sure if relevant 
- yet
+                               default:
+                                       break;                          
+                       }
+                       blockWeight += clientWeight;
+               }
+       }       // end client opinion requests
+               
+               // now how the "opinions" work:
+               
+       uint8 delta = 0, newLevel = PerfModeLevel(mode);
+               
+       if (blockWeight != 0){
+               if (faster){
+                       delta = PerfModeLevel(mode) - 
PerfModeLevel(fPerformanceMode);
+               
+                       if (blockWeight <= 64 && delta > 2)
+                               newLevel -= 1;
+                               
+                       if (blockWeight <= 128 && delta > 1)
+                               newLevel -= 1;
+                               
+                       if (blockWeight <= 256 && delta > 1)
+                               newLevel -= 2;  // possibly denying change
+                               
+                       if (blockWeight > 256) // deny change
+                               newLevel = PerfModeLevel(fPerformanceMode);
+                               
+               }else{  // want to go slower...
+                       delta = PerfModeLevel(fPerformanceMode) - 
PerfModeLevel(mode);
+                       
+                       if (blockWeight <= 64 && delta > 2)
+                               newLevel += 1;
+                               
+                       if (blockWeight <= 128 && delta > 1)
+                               newLevel += 1;
+                       
+                       if (blockWeight <= 256 && delta > 1)
+                               newLevel += 2;  // possibly denying change
+                               
+                       if (blockWeight > 256)  // deny change
+                               newLevel = PerfModeLevel(fPerformanceMode);
+
+               }// end slower
+       } // end has some blockWeight
+       
+       if (force && PerfModeLevel(mode) != newLevel)
+               return false;   // no changes for all that work...
+               
+       fPerformanceMode = PerfModeByLevel(newLevel);
+       return PerfModeLevel(mode) <= PerfModeLevel(fPerformanceMode);
+       
+}
+
+
+
+
diff --git a/src/servers/app/drawing/compositing/CompositeEngine.h 
b/src/servers/app/drawing/compositing/CompositeEngine.h
index eb34d55..e612bfd 100644
--- a/src/servers/app/drawing/compositing/CompositeEngine.h
+++ b/src/servers/app/drawing/compositing/CompositeEngine.h
@@ -13,69 +13,13 @@
 #include <OS.h>
 #include <String.h>
 
+#include "CompositingPrivate.h"
 #include "HWInterface.h"
 #include "RenderingBuffer.h"
 #include "ServerBitmap.h"
 #include "UpdateQueue.h"
 
-/*
-       performance_mode determines the rate at which we will update changes
-       in the back-buffer into the front-buffer.
-       We batch updates together and change the performance mode based on the
-       amount of changes made, the area covered - along with app-requested 
-       performance modes (new API) or ServerWindow requests based on user
-       action (window resize/move, typing, etc...)
-       Just becauuse we are in, say, FULL_PERFORMANCE_MODE does not mean we
-       will actually be operating at a full 60 fps, that is just the reference
-       update interval (1/60th of a second [minus some time for overhead])     
-*/
-enum performance_mode{
-               STOP_PERFORMANCE_MODE = 0,      //   0  fps (screen off)
-               SLOW_PERFORMANCE_MODE = 5,      // <= 5 fps (sitting at the 
desktop)
-               MILD_PERFORMANCE_MODE = 15,     // < 15 fps (normal GUIs, low 
motion)
-               HIGH_PERFORMANCE_MODE = 30,     // < 30 fps (videos, moderate 
motion)
-               FULL_PERFORMANCE_MODE = 60,     // ~ 60 fps (animations, moving 
video)
-               SYNC_PERFORMANCE_MODE = 120,// @ refresh rate - up to 120hz
-               WILD_PERFORMANCE_MODE = 1000// max power! - up to 1000fps...
-};
-
-enum composite_mode{
-               NORMAL_COMPOSITE = 0//, // CPU[s] do[es] the work
-       //      ACCEL_COMPOSITE,        // GPU accelerated
-       //      MIXED_COMPOSITE,        // CPU does some, GPU does some
-       //      XGPUS_COMPOSITE,        // multiple GPUs for compositing
-       //      XHEAD_COMPOSITE         // treat monitors separately -
-                                                               // one 
workspace per monitor ;-)
-};
-
-/*
-       composite_client_type
-       
-       It is often useful for the CompositeEngine to know what type of client
-       is denying or making a request so as to react properly.
-       
-       Basically, if a Desktop requests STOP_PERFORMANCE_MODE, that means the
-       monitor has gone to black (or is going to sleep).  If a Window asks, we
-       will outright deny it.  If a workspace asks, and we are in 
XHEAD_COMPOSITE,
-       then we stop updates for the screen for that workspace, only increasing
-       when the workspace permits us.
-       
-       This allows us to not touch the code too much in the future.
-               
-       A CompositeEngineClient can identify itself as being of one of types
-       as follows:
-*/
-enum composite_client_type{
-       ANONYMOUS_COMPOSITE_CLIENT      = 0,
-       DESKTOP_COMPOSITE_CLIENT,
-       DESKTOPWINDOW_COMPOSITE_CLIENT,
-       WORKSPACE_COMPOSITE_CLIENT,
-       WINDOW_COMPOSITE_CLIENT,
-       SERVERWINDOW_COMPOSITE_CLIENT,
-       DIRECTWINDOW_COMPOSITE_CLIENT,
-       UPDATEQUEUE_COMPOSITE_CLIENT
-};
-
+using namespace BPrivate;
 class Window;
 
 class CompositeEngineClient{
@@ -88,7 +32,7 @@ public:
        virtual void                            CompositingEnabled(bool 
enabled) = 0;
 
 
-       // optional:
+       // optional override:
 
        // if you need to do something BEFORE compositing takes over
        // or before it ceases to render you need to override one of the 
following:
@@ -97,28 +41,44 @@ public:
        
        virtual void                            
CompositingChanged(performance_mode,
                                                                                
                        composite_mode);
-       virtual void                            CompositingPerformance(bool 
isLow = true);
+                                                                               
                        
+       virtual void                            CompositingPerformanceSlow(bool 
isSlow);
+               // this is triggered to inform a client that they will be 
getting
+               // less attention for one of the reasons as follows:
+                       /*
+                               1. Screen-saver is active
+                               2. Entered into SLOW or STOP performance mode
+                               3. System is bogged down
+                               
+                               When isSlow is true, you should consider 
limiting updates
+                               and redraws until isSlow comes back as false.
+                       */
        
        // affect operations
        
        // When a mode change is to be made we ask our clients if it is 
acceptable.
-       // Your opinion is just that - an opinion ;-)  Unless you are a 
Desktop...
-       virtual bool                            
CompositingModesRequested(performance_mode,
+       // Your opinion is just that - an opinion ;-)
+       virtual bool                            
CompositingModeRequested(performance_mode,
                                                                                
                                        composite_mode);
-       
-                       
+                               // your opinion about composite_mode doesn't 
matter... it is there
+                               // just so you can take it into account if you 
need to...
+
                        void                            
MarkScreenRegionDirty(BRegion&);
+                               // this may seem like an odd place for this, 
but it is not...
                        
                        // tell the composite engine that you need to be 
treated better
                        // or that you are being treated too well.
                        // There are five (unnamed) priority levels (0-4)
                        // everyone starts at zero (lowest priority).
-                       void                            
IncreaseCompositeClientPriority();
-                       void                            
DecreaseCompositeClientPriority();
-                       void                            
SetCompositeClientPriority(uint8);
+                       // Increasing priority gives your update entries added 
strength and
+                       // increases the strength of your opinions
+                       // It is best to stay at zero, only increasing as it 
becomes more
+                       // important for you to get your way.
+                       // Even Desktop has a priority of zero & only escalates 
as needed.
+                       uint8                           
IncreaseCompositeClientPriority();
+                       uint8                           
DecreaseCompositeClientPriority();
+                       uint8                           
SetCompositeClientPriority(uint8);
        
-                       uint8                           
CompositeClientPriorityLevel() const;
-                       
                        // If requested mode (or higher) is achieved, true is 
returned.
                        // there are few scenarios in which these will fail...
                        bool                            
SuggestCompositingMode(performance_mode,
@@ -126,11 +86,29 @@ public:
 
                        bool                            
RequireCompositingMode(performance_mode,
                                                                                
composite_mode = NORMAL_COMPOSITE);
-                       
+
+               composite_client_type   CompositeClientType() const;
+               
+                       bool                            
SetCompositeClientFullscreen(bool);
+                       uint8                           
CompositeClientPriority() const;
+
+                       bool                            
SetToFullscreenMode(Window*, bool enable)
+                       {
+                                       return false;
+                       }
+               
+ private:
+               composite_client_type   fClientType;
+               
+               bool                                    fFullscreen;
+               
+               uint8                                   fPriority;
+               
+               BString                                 fName;                  
 };
 
 
-class CompositeEngine : public HWInterfaceListener{
+class CompositeEngine{
 public:
        explicit                                        CompositeEngine();
                                                                
~CompositeEngine();     // no use for a vtable...
@@ -143,7 +121,9 @@ public:
                        status_t                        
SetCompositingEnabled(bool enable);
                                                                // synchronous
                
-                       size_t                          TotalMemoryUsage();
+                       size_t                          CalculateMemoryUsage();
+                       size_t                          EstimateMemoryUsage()   
const;
+                       size_t                          FrameBufferSize()       
const;
                        size_t                          
LimitMemoryUsage(size_t);
                                // returns actual limit approved
                        
@@ -156,15 +136,16 @@ public:
                                                                                
listener);
 
                        uint8                           CurrentFPS()    const;
-                       uint8                           MaxFPS()                
const;
                        
                        performance_mode        PerformanceMode()       const;
-                       bool                            
RequirePerformanceMode(performance_mode mode);
+                       bool                            
RequirePerformanceMode(performance_mode mode,
+                                                                               
CompositeEngineClient* client);
                                // if we can't get the mode (or higher) we 
don't try to elevate
                                // we simply return false and remain in 
whatever mode we were
                                // already in.
                        
-                       bool                            
SuggestPerformanceMode(performance_mode mode);
+                       bool                            
SuggestPerformanceMode(performance_mode mode,
+                                                                               
CompositeEngineClient* client);
                                // SuggestPerformanceMode() will do its best to 
elevate to as
                                // close to the requested mode as possible.  
The reasons for
                                // the mode to not elevate are as follows:
@@ -195,7 +176,7 @@ public:
                        
                        void                            DrawWindow(Window*);
                        
-                       void                            
SetFullScreenWindow(Window*);
+                       bool                            
SetToFullscreenMode(Window*, bool);
                                // disables background updates...
                        
                        // full-screen fading (synchronous)
@@ -212,20 +193,24 @@ private:
        static  int32                           _SlaveRenderThread(void*);
        static  int32                           _BackToFrontThread(void*);
        
+                       void                            _EnforceMemoryLimit();
                        BRect                           _NextUpdateRect(bool&);
                        uint8                           
_NextUpdateBatchWeight();
                        void                            _PushToFront();
-                       void                            
_SetPerformanceMode(performance_mode);
+                       bool                            
_SetPerformanceMode(performance_mode,
+                                                                               
CompositeEngineClient* client,
+                                                                               
bool force, bool lock = false);
                        
-                       BLocker                         fClientsLock,
+       mutable BLocker                         fClientsLock,
                                                                fModeSwitchLock,
-                                                               fMasterLock;
+                                                               fMasterLock,
+                                                               
fBackToFrontLock,
+                                                               fHardwareLock;
                        
                        BObjectList<CompositeEngineClient>
                                                                fClients;
                        
                        uint8                           fFrames_Max,
-                                                               fFrames_Average,
                                                                fFrames_Target,
                                                                
fUpdates_PendingPriority;
                        
@@ -237,7 +222,15 @@ private:
                        performance_mode        fPerformanceMode,
                                                                
fPerformanceMode_Last;
                        
+                       composite_mode          fCompositeMode;
+                       
                        bool                            fCompositingEnabled     
        : 1;
+                       
+                       HWInterface*            fHardware;
+                       
+                       size_t                          fMemoryLimit,
+                                                               
fFrameBufferSize,
+                                                               
fEstimatedMemoryUsage;
                                                                
 };
 
diff --git a/src/servers/app/drawing/compositing/Jamfile 
b/src/servers/app/drawing/compositing/Jamfile
index 8751fc3..5b3f3cc 100644
--- a/src/servers/app/drawing/compositing/Jamfile
+++ b/src/servers/app/drawing/compositing/Jamfile
@@ -14,5 +14,6 @@ UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing 
Painter font_support
 UseHeaders $(HAIKU_FREETYPE_HEADERS) : true ;
 
 StaticLibrary libasdrawing.a :
+       CompositeEngine.cpp
        CompositeUpdateQueue.cpp
 ;

############################################################################

Commit:      ca740996653746647b85e29f05a33620a23cab20

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Tue Mar 27 23:53:12 2012 UTC

Major commit

Re-oriented ComositeEngine scrap pieces from CAFE::RenderEngine, namely 
removing performance modes - as these aren't likely needed int the limited role 
in the app_server.
If anything, the app_server will only need three modes: slow(5hz), 60hz, 
@refresh, which is better handled with SetSlowMode() and 
SetUpdateEveryRefresh().

Moved special accessors to CompositingPrivate.  Prepared app_server port 
communication, implemented some BWindow changes (SetDrawingMode()), prepare for 
special
full-screen modes to prevent unneeded updates from the back coming forward.

Created WindowBuffer, which will be atttached to a Painter with a new method to 
render the buffer directly, which is attached to a standard RenderEngine, which 
will be generated by
the CompsiteHWInterface.  WindowBuffer will collect updated rects and the 
CompositeEngine will prioritize updates front-to-back, ceasing updates when a 
new frame is to be renderred
- but not before completing updates for any active WindowBuffer.

While WindowBuffer is active with the CompositeEngine, the client will be 
unable to make drawing changes, so we will push as many threads to each 
WindowBuffer as possible, with each
dirty rect possibly being handled by a separate thread/core and unlock that 
WindowBuffer as quickly as possible.

----------------------------------------------------------------------------

diff --git a/headers/private/app/CompositingPrivate.h 
b/headers/private/app/CompositingPrivate.h
index ff196e4..f37a28d 100644
--- a/headers/private/app/CompositingPrivate.h
+++ b/headers/private/app/CompositingPrivate.h
@@ -1,3 +1,7 @@
+/*
+       The function names are quite long...sorry!
+*/
+
 #ifndef COMPOSITING_PRIVATE_H
 #define COMPOSITING_PRIVATE_H
 
@@ -8,136 +12,60 @@ class BWindow;
 
 namespace BPrivate{
 
-/*
-       performance_mode determines the rate at which we will update changes
-       in the back-buffer into the front-buffer.
-       We batch updates together and change the performance mode based on the
-       amount of changes made, the area covered - along with app-requested 
-       performance modes (new API) or ServerWindow requests based on user
-       action (window resize/move, typing, etc...)
-       Just becauuse we are in, say, FULL_PERFORMANCE_MODE does not mean we
-       will actually be operating at a full 60 fps, that is just the reference
-       update interval (1/60th of a second [minus some time for overhead])     
-*/
-enum performance_mode{
-               STOP_PERFORMANCE_MODE = 0,      //   0  fps (screen off)
-               SLOW_PERFORMANCE_MODE = 5,      // <= 5 fps (sitting at the 
desktop)
-               MILD_PERFORMANCE_MODE = 15,     // < 15 fps (normal GUIs, low 
motion)
-               HIGH_PERFORMANCE_MODE = 30,     // < 30 fps (videos, moderate 
motion)
-               FULL_PERFORMANCE_MODE = 60,     // ~ 60 fps (animations, moving 
video)
-               SYNC_PERFORMANCE_MODE = 120,// @ refresh rate - up to 120hz
-               WILD_PERFORMANCE_MODE = 1000// max power! - up to 1000fps...
-};
-
-enum composite_mode{
-               NORMAL_COMPOSITE = 0//, // CPU[s] do[es] the work
-       //      ACCEL_COMPOSITE,        // GPU accelerated
-       //      MIXED_COMPOSITE,        // CPU does some, GPU does some
-       //      XGPUS_COMPOSITE,        // multiple GPUs for compositing
-       //      XHEAD_COMPOSITE         // treat monitors separately -
-                                                               // one 
workspace per monitor ;-)
-};
 
-/*
-       composite_client_type
-       
-       It is often useful for the CompositeEngine to know what type of client
-       is denying or making a request so as to react properly.
-       
-       Basically, if a Desktop requests STOP_PERFORMANCE_MODE, that means the
-       monitor has gone to black (or is going to sleep).  If a Window asks, we
-       will outright deny it.  If a workspace asks, and we are in 
XHEAD_COMPOSITE,
-       then we stop updates for the screen for that workspace, only increasing
-       when the workspace permits us.
+typedef struct shadow_config{
+       uint8                   alpha,  red, green, blue,       // color
+                                       width,          // shadow width from 
decorator
+                                       depth,          // how many windows get 
shadows...
+                                       blend_rate;     // how quickly to blend
+                                       
+       BString*                addonName;      // NULL if not one!!
        
-       This allows us to not touch the code too much in the future.
-               
-       A CompositeEngineClient can identify itself as being of one of types
-       as follows:
-*/
-enum composite_client_type{
-       ANONYMOUS_COMPOSITE_CLIENT      = 0,
-       DESKTOP_COMPOSITE_CLIENT,
-       DESKTOPWINDOW_COMPOSITE_CLIENT,
-       WORKSPACE_COMPOSITE_CLIENT,
-       WINDOW_COMPOSITE_CLIENT,
-       SERVERWINDOW_COMPOSITE_CLIENT,
-       DIRECTWINDOW_COMPOSITE_CLIENT,
-       UPDATEQUEUE_COMPOSITE_CLIENT,
-       FULLSCREEN_COMPOSITE_CLIENT     // screensaver, game, etc...
+       shadow_config():        alpha(50), red(0), green(0), blue(0),
+                                               width(5), depth(1), 
blend_rate(128),
+                                               addonName(NULL){}
+       ~shadow_config(){delete addonName;}
 };
 
-
-/*
-typedef struct CompositingStatus{
-       bool                                    enabled;
-       bigtime_t                               timeEnabled;
-       performance_mode                performanceMode;
-       composite_mode                  compositingMode;
-       int32                                   frameRate,
-                                                       averagesUpdates;        
// per refresh
-       
-       size_t                                  memoryLimit,
-                                                       memoryUsageEstimate;
-       
-       bool                                    mouseIsOverlay,
-                                                       shadowsEnabled,
-                                                       dimmingEnabled,
-                                                       fullscreenActive;
-       

[ *** diff truncated: 1837 lines dropped *** ]


############################################################################

Commit:      5df5c102c2fc75818f339719402d11ae8751511f

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Wed Mar 28 22:55:44 2012 UTC

Adding needed funcitonality to Window:

Ability to use WindowBuffer (for compositing OR caching).

Bring numerous other objects in line with changes.

Take into account requirements for hardware acceleration.

CompositeHWInterface is now an AccelerantHWInterface.

Trying to limit requirements in the future for acceleration.

NOTE:  the build will not link at this point, still on purpose...

----------------------------------------------------------------------------

############################################################################

Commit:      55b3b782cc5fa0172e026c2ed02d8cfd2ce78214

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Wed Mar 28 23:52:11 2012 UTC

Implement some missing functions.

Found some lacking areas, and implemented missing WindowBuffer functions.

CompositeEngine is only hold-up until link success.

----------------------------------------------------------------------------

############################################################################

Commit:      9cd2054810a019964e29eac906c744b75b18b93a

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Thu Mar 29 01:56:42 2012 UTC

Various tidbits.

----------------------------------------------------------------------------

############################################################################

Commit:      d6c9717f1e2ba3574e4fa8f85129089aa4092d94

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Thu Mar 29 21:49:23 2012 UTC

Message Handling

Setup message handling for compositing.

The CompositeEngine will handle all of its own requests.

This is merely a prelude before setting up a route around ServerApp to 
expediate communications.

Purpose being that some messages will undoubtedly be very time sensitive... and 
having all handling code in one place is quite nice.

Began changes and made first runs of modified app_server (without incident, but 
no regression testing-yet).

app_server now builds.

Modified binaries thus far: libbe.so, app_server

----------------------------------------------------------------------------

############################################################################

Commit:      86d79d7db4618cf741cb7256c1c69328ed40eb00

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Fri Mar 30 00:31:29 2012 UTC

Bug fixes

Test run with compositing enabled to trace down bugs.  Found several - as 
expected.

----------------------------------------------------------------------------

############################################################################

Commit:      79c4de7d12c73d8cddd5844b7db38c54bd1ab3a4

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Fri Mar 30 01:04:47 2012 UTC

Adapt view to local buffer coordinates for drawing.

Hoping this way works - it did eliminate all segment violations up to the 
Desktop bitmap draw, so we are no longer overunning the buffers it would seem...

This is being kept as its own commit so it can be easily undone later, or 
referenced.

----------------------------------------------------------------------------

############################################################################

Commit:      3823042ff2d6502ca7b3d2528d7d4a21e88bf8ca

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Fri Mar 30 23:06:59 2012 UTC

Working out the kinks...

As we are now much more sensitive to writing outside of a View's bounds, we 
have to make adjustments...

I believe I will be making Painter more aware of it's buffer's limitations, and 
to act accordingly to prevent segment violations.

At this point, app_server can run in compositing mode, though nothing is 
painted on the screen.  However, with very little effort (just clicking around) 
we find
ourselves with a segment violation in Window SeetDrawingBuffer(), IIRC...  next 
commit ;-)

----------------------------------------------------------------------------

############################################################################

Commit:      a649fe99b33faf3b6e1c544194debadeaf479d35

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Sun Apr  1 14:46:33 2012 UTC

Re-orienting to mixed-compositing (temporarily)

Removed Window::SetDrawingMode in preference to the original B_RENDER_COMPOSITE 
window flag.
The app_server internals make so many assumptions that drawing is occuring 
directly in the screen coordinate space that I am having surprising difficulty 
getting even a single
Window to draw into its own WindowBuffer without some code blasting past the 
boundaries (and thus crashing).

Decorators now draw directly into the screen buffer, but will soon be rewritten 
to draw into the  over-provisioned WindowBuffers of their 'owning' windows.

Currently, using the app_server without compositing enabled is going to be 
fruitless, and compositing still defaults to disabled, so don't expect to build 
a usable app_server -
though it does build without issue.

Modified View to use ConvertForDrawing instead of ConvertToScreenForDrawing.  
The functions are still very rudimentary, will be cloned in WindowBuffer, and 
the View functions will
call into WindowBuffer to ascertain the proper drawing area.

Further, the disconnect of DrawingEngine and its owner must be dissolved.  And 
Painter with its buffer...

Both must be made aware of their drawing space so they do no attempt to write 
outside of it, but intelligently clip their drawing.  Each with their own 
degree of agressiveness and
reaction.

----------------------------------------------------------------------------

############################################################################

Commit:      7104d4bcc1e3dd4fea5898b1c7fc9df609d634c1

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Sun Apr  1 22:31:45 2012 UTC

Assorted tidbits

Found chicken/egg problem in Window constructor which was causing problems.  
Things are much better now.

Decided against using UpdateQueue in preference to dual BRegion for the 
WindowBuffer.  Window's UpdateSession may be used instead when I get further 
along.

Decorators are very confused as to dirty regions, but I am preparing to 
over-provision WindowBuffer to optimize resize performance and to permit room 
to draw the decorator directly
into the WindowBuffer.

Clipping will prevent window content spill-over, but decorators will be able to 
draw over the window (but should avoid it, naturally).

Decorator changes are coming soon - the order of initialization may change 
radically - but it may not...

----------------------------------------------------------------------------

############################################################################

Commit:      d4f54d1dde0c860a823e3743a28c521c74c57902

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Tue Apr  3 23:20:13 2012 UTC

Re-orientation to new model...

-Decided to change the methodology for View's ConvertForDrawing() to convert up 
through the parents all of the way to the window.  The window then does the 
final conversion based
upon its type:

        Window: converts drawing to screen coordinate space
        OffscreenWindow: does no further conversion
        CompositeWindow: converts to WindowBuffer coordinate space

        (Others will inherit the behavior from Window, but I will investigate 
the need to override such behavior.)

-Virtualized many functions in Window to facilitate a functional 
CompositeWindow typee so as to keep the code paths separate.

-Making first steps to have WindowBuffer stay alive even after a Window's 
Quit() or destruction until all referencing objects have adapted or been 
destroyed.
        WindowBuffer is now a BReferenceable & only BReference<WindowBuffer> 
will be passed around.
        TODO: DrawingEngine will manually call AcquireReference() and 
ReleaseReference() if casting to WindowBuffer succeeds.
                Why: this greatly simplifies locking, and also permits 
lazy-recycling of allocated buffer spaces in the future.

I believe all other changes are in-ine with the abovee.

This will not build.  Will probably spout out many many errors.

Will certainly not link ;-)

----------------------------------------------------------------------------

############################################################################

Commit:      7117024f8d2f8226724266e7df97da5e4cdf3d59

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Wed Apr  4 16:24:22 2012 UTC

Moving Along

Further implementing CompositeWindow.

Re-wrote WindowBuffer's _ResizeTo() function with tested & working code.

Compiles, will not link.  Much work to go.

----------------------------------------------------------------------------

############################################################################

Commit:      b59f6ceaa131c5dac8981740ad5c577e7c140c19

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Wed Apr  4 21:24:38 2012 UTC

Bug fix, misc...

----------------------------------------------------------------------------

############################################################################

Commit:      e8b91bdb2f392cd530bf28726b29eb3be42ca4af

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Thu Apr  5 00:38:40 2012 UTC

Fixes

Non-compositing mode now mostly works properly again.

There are probably a few bugs here and there, but they should be minor(or 
obvious).

Ran into an interesting situation where View::ConvertToWindow() somehow 
converts all of the way to the screen, which makes no sense... somewhere the 
drawing instructions are being
converted from window coordinates to screen coordinates - and I can't find it...

I checked in both View.cpp files (src/kits, and src/servers/app), ServerWindow 
(which receives the drawing messages from BView), and the ConvertToParent() 
code to try and solve this
dilemma.  I even had ever single view spout out its frame to make sure the view 
attached to the window had an origin of (0,0) - and they all did...

Next commit will hopefully solve this...

----------------------------------------------------------------------------

############################################################################

Commit:      443ba22c684cc41b18117cf05e76ecd0f2dcae21

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Thu Apr  5 22:11:02 2012 UTC

Bug fix

Figured out the problem with View::ConvertForDrawing(*) - ConvertToParent when 
there is no parent results in an undesired result (though it seems like it 
shouldn't do anything.. the
frame should be (0,0,rt, bt).

----------------------------------------------------------------------------

############################################################################

Commit:      c52e7f21c19a2a4a1f4dfd737bf86beda04d64ef

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Fri Apr  6 00:32:40 2012 UTC

Continuing progress.

CompositeHWInterface taking over for AccelratedHWInterface.

CompositeWindow taking over for Window (for non-offscren windows only).

Temporary B_RENDER_COMPOSITE flag being utilized to force a single window into 
compositing for testing.

Logging levels reduced to eliminate tested code-paths.  Further reductions 
forth-coming.

DrawingEngine now capable of having a RenderingBuffer manually set via its 
public API. RenderingBuffer now capable of being aware of such changes to 
augment lazy-allocation
techniques - or other uses (such as knowing when we are no longer being 
modified...).

Builds.  Runs.  Works.  Drawing doesn't seem to be re-routed to set 
RenderingBuffer, so there is some logging in place to trace that issue...

----------------------------------------------------------------------------

############################################################################

Commit:      eb34894293ebf80d5645ff540eac4cf3b05a1eb3

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Sat Apr  7 23:21:12 2012 UTC

Bug fixes & more prep-work

WindowBuffer:
        fWindowFrame was not being updated.
        Over-provisioning was being added at the wrong time - thereby not bein 
applied at all.
        Cleaned up the code and removed interim window frame as the window 
frame must change for each and every resize event.

CompositeWindow
        Setup to use a new method to temporarily mark a test window as 
compositing.

Decorator:
        Preparing to drastically change how drawing is handled in Decorator.
        Will implement BView-style drawing interfaces, and hide much of the 
tedium.
        This is important as a Decorator may draw in foreign coordinate systems 
- such as WindowBuffer's.
        All frames and drawing will be relative to the window frame.
        Move events will need to be blocked entirely from a custom decorator's 
awareness.

app_server builds & runs.  An odd memory leak is still occuring in relation, I 
believe, to WindowBuffer... which is an odd situation... after WindowBuffer is 
destroyed, some RAM
seems to not be returned to the system.  Will need to chase this down.

----------------------------------------------------------------------------

############################################################################

Commit:      1e36feeee65807731468f65e7dcbf8525cfdab8a

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Sun Apr  8 11:04:58 2012 UTC

Correct oversight.

WindowBuffer was meant to hold its largest size in both dimensions, but any 
time a new max was achieved in either dimension it'd lose the other dimension's 
previous setting.

This commit resolves this.

On a side note:  verified performance increase of other commits in 
non-compositing mode.  Slightly faster than anticipated.

----------------------------------------------------------------------------

############################################################################

Commit:      bd713a3d3c513f1362cccf25ae353f8cacddddd0

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Tue Apr 10 21:37:03 2012 UTC

Test drawing WindowBuffer to frame buffer

CompositeEngine::Draw() working better - also not locking exclusively & for a 
much shorter duration.

There seems to be some issues with DrawBuffer(), it draws very quickly, but 
there are large black regions seemingly even outside the drawing region... very 
strange.

Created AlphaRegion to hold and compute the WindowBuffer region's alpha areas 
as well as the screen's for fast reference.  The theory is that the screen's 
alpha
region will be updated for every window movement (focus changes, moving 
windows, minmizations, blocking, etc...) and each WindowBuffer's region will be 
largely
stagnant, or will change relatively slowly.  It is one consideration into the 
forthcoming Compositing Optimization Guide for Haiku application developers.

----------------------------------------------------------------------------

############################################################################

Commit:      537a2cabe7d841c0dd1daf5c9c814b232a1750f4

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Thu Apr 12 01:11:14 2012 UTC

Cleaned up CompositingPrivate

Haven't even tried compiling these changes.

RenderSession may or may not persist, just exploring matters...

Having hard drive difficulties so I thought it best to push these changes up 
ASAP.

----------------------------------------------------------------------------

############################################################################

Commit:      388e1affb237f576dce3265c23c61517c60ed723

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Fri Apr 13 00:33:58 2012 UTC

Coding with headache == hard

Correcting mistakes and completing initial CompositingPrivate changes.

Removed RenderSession, may have windows maintain visible regions.

Compiles - haven't tested running yet, but there should be no new issues.

----------------------------------------------------------------------------

############################################################################

Commit:      6fe07471eb0087168b29d1729f82472ec6ba103a

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Fri Apr 13 22:49:49 2012 UTC

More client-server comms

Flesh out more of the CompositeEngine communication protocol.  There is 
currently a stalling issue with getCompositingConfig() in CompositingProvate.

Began to flesh out the fundamental server-side requirements for 
BCompositeOverlay, which is a BBitmap which accepts views and will provide 
numerous special-purpose features (such as
locking to mouse movement and likely other conditions).

Decided to make over-provisioning configurable.  Also re-worked 
BWindow::_RequestEffect() to not use a BMessage by internally converting an 
uint32 to BPrivate::effect_type.

Builds & runs.  Have observed a performance increase in non-composited mode.  I 
believe this is due to the optimizations in the code-paths for 
ConvertForDrawing vs
ConvertToScreenForDrawing.  The latter, IIRC, used a side-effect to work up 
view hierarchy which resulted in numerous vtable lookups.  Don't quote me on 
that though... long time
since I looked at the original code ;-)  My guess of +0.5fps in 
CompositePerfTest3 was about spot-on, seeing about +0.75fps in VMWare.

----------------------------------------------------------------------------

############################################################################

Commit:      67b90e34a3c9737c1b8e4bdcf14809898638c386

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Sat Apr 14 23:56:43 2012 UTC

CompositeOverlay

More CompositeOverlay work.

I believe this should remain public API, but perhaps not until compositing is 
more stabilized.

----------------------------------------------------------------------------

############################################################################

Commit:      6ad2af33ca7243630c3a2b6373f6635bd8068680

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Sun Apr 15 14:20:31 2012 UTC

BCompositeOverlay

Public API should now be final.  Client code should be functional.  Server-side 
code still just a place-holder.

Compiles & links once again.

TODO: need to convert rgb_color to a fill pattern based upon BBitmap's color 
space rather than using the accelerant's conversion in case the video driver 
uses a different pattern
and will convert the bitmap before displaying on-screen.  I doubt this is a 
problem on x86 these days, but other platforms will likely also desire the 
compositing features.

----------------------------------------------------------------------------

############################################################################

Commit:      090b4504b48ec428a4204f393f0e864314777cbd

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Mon Apr 16 01:36:31 2012 UTC

Server-side CompositeOverlay

Setting up the server-side of things for BCompositeOverlay.

Also touched a couple of other areas as I ran into things that need to be 
implemented now or in the future.

Compiles - will not link (missing CompositeEngine::Hide(CompositeOverlay*) and 
Show(...)).

----------------------------------------------------------------------------

############################################################################

Commit:      4687592535a3a7cdf3529a3e1ef2a6d46fbc948a

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Wed Apr 18 23:17:17 2012 UTC

Adjust to requirements.

Found most of the reason why the drawing was all weird... mostly due to 
clipping - which I anticipated...

Further investigated the conversion requirements, and stripped out unneeded 
virtual overrides.

Making some attempts to improve performance, I have investigated the need for 
alpha regions - determined they are more vital than ever if we hope to have 
CPU-based compositing with
an acceptable performance level...

Preparing for cursor overlays, and a few other tidbits.

----------------------------------------------------------------------------

############################################################################

Commit:      1489f21a65cc70da3b2380c9e331306dd05dd182

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Sat Apr 21 01:18:29 2012 UTC

Coordinate conversion & optimization

Added ability to convert back from the window's coordinate space to a view for 
various current and future uses.

"Profiled" code paths to determine usage and performance, decided optimization 
was called for - and was surprised by the end result.  CompositePerfTest3 went 
from 24FPS to 27FPS -
with just 12bytes or so of RAM per view extra...  Also cleans up the code 
nicely ;-)

Wish I had more time... and that I weren't sick :-(

----------------------------------------------------------------------------

############################################################################

Commit:      76dfc16cc25448807d2ed6e28a45de749c95554e

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Mon Apr 23 20:27:27 2012 UTC

ScreenStateGrid & more

ScreenStateGrid represents the visible screen as a grid of cells.  It is just 
an unfinished header at this point.

Made changes to some comments to better suit the understandability to the 
uninitiated (i.e.... everyone else but me...).

Also preparing CompositeEngine to use ScreenStateGrid, and to re-purpose 
Desktop's window listing rather than having its own.  Z-order will be handled 
by sorting the Desktop's
window list.  The desktop window will be window 0, and the top-most window will 
be at the highest index.

Also a bit of extra loop unrolling to help speed up the final render task - 
more unrolling may be worthwhile, but it could be counter-productive at the 
same time...

----------------------------------------------------------------------------

############################################################################

Commit:      e12c27cf6c418b7467a7a10c288229963cea9e71

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Mon Apr 23 22:27:40 2012 UTC

Poor scaling, so re-designed

Quick-n-dirty performance test of a faux-ScreenStateGrid determined that the 
grid method would have poor scalability at higher resolutions.  It was faster 
at 1024x768 and below, but
from there became slower.

Mutated ScreenStateGrid into CompositeScreenStates, which holds numerous 
regions an interplexes them to gain the necessary output regions.

----------------------------------------------------------------------------

############################################################################

Commit:      57a09efe27371b022b4807139f4e74ac6e2c3259

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Mon Apr 23 23:40:29 2012 UTC

Re-orient towards CompositeScreenStates

Haven't test CompositeScreenStates yet, so that is next on my todo list (off 
git).

CompositeEngine's crude test-mode Draw() function has been gutted as it was no 
longer usable.

Once CompositeScreenStates is verified, I will be moving to direct full-mode 
compositing of all windows, working out the kinks as they come along.

----------------------------------------------------------------------------

############################################################################

Commit:      fe7207954e1107589c440b9181a85a2a4fcc352f

Author:      looncraz <looncraz@xxxxxxxxxxx>
Date:        Tue Apr 24 02:03:44 2012 UTC

CScreenStates verified (well enough for now, anyway)

No changes needed to CScreenStates - seems to work like a charm.  Re-oriented 
towards using it, will be working window events back up the (logical) object 
stack to assure all is
well.

Next temporary draw routine will cycle through every window, in order, in the 
dirty region and draw them.  It will then perform the alpha-mode render.  
Performance will be sad, but
it will be required to make further progress.

----------------------------------------------------------------------------


Other related posts:

  • » [haiku-commits] BRANCH looncraz-github.compositing - src/servers/app/drawing/compositing src/servers/app src/kits/interface headers/private/app src/kits/app - looncraz-github . compositing