app_server: add new BView layers API

* Add new methods
    BView::BeginLayer(uint8 opacity)
    BView::EndLayer()

* All drawing between begin and end of a layer is redirected onto an
  intermediate bitmap. When ending the layer, this bitmap is
  composited onto the view with the opacity given when the layer was
  started.

* Layers can be nested arbitrarily and will be blended onto each
  other in order. There can also be any arbitrary interleaving of
  layer begin/end and drawing operations.

* Internally, drawing commands are redirected into a BPicture between
  BeginLayer and EndLayer (but client code need not know or care
  about this). Client code can also start/end other BPictures while
  inside a layer.

* Uses the PictureBoundingBoxPlayer to determine the size of the
  layer bitmap before allocating and drawing into it, so it does not
  allocate more memory than necessary and -- more importantly -- it
  will not alpha-composite more pixels than necessary.

* Drawing mode is always set to B_OP_ALPHA, blend mode to
  (B_PIXEL_ALPHA, B_ALPHA_COMPOSITE) while inside layers. This is
  necessary for (a) correct compositing output and (b) for
  redirection of drawing into the intermediate bitmap, which uses the
  renderer_region offset (in B_OP_COPY, the Painter does not use the
  AGG renderer methods, it directly accesses the pixel data. This
  would access out-of-bounds without the offset, so B_OP_COPY cannot
  be allowed.)
  To ensure these modes aren't changed, BView::SetDrawingMode()
  and BView::SetBlendingMode() are ignored while inside a layer.

* The main motivation behind this new API is WebKit, which internally
  expects such a layers functionality to be present. A performant and
  reusable implementation of this functionality can only be done
  server-side in app_server.
This commit is contained in:
Julian Harnath 2015-07-25 15:44:23 +02:00
parent d56beda4d8
commit 551438b9be
19 changed files with 489 additions and 14 deletions

View File

@ -505,6 +505,9 @@ public:
void DrawPictureAsync(const char* filename,
long offset, BPoint where);
void BeginLayer(uint8 opacity);
void EndLayer();
status_t SetEventMask(uint32 mask, uint32 options = 0);
uint32 EventMask();
status_t SetMouseEventMask(uint32 mask,

View File

@ -7,6 +7,7 @@
* Jérôme Duval, jerome.duval@free.fr
* Axel Dörfler, axeld@pinc-software.de
* Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk>
* Julian Harnath, <julian.harnath@rwth-aachen.de>
*/
#ifndef APP_SERVER_PROTOCOL_H
#define APP_SERVER_PROTOCOL_H
@ -319,6 +320,8 @@ enum {
AS_VIEW_SET_VIEW_BITMAP,
AS_VIEW_SET_PATTERN,
AS_SET_CURRENT_VIEW,
AS_VIEW_BEGIN_LAYER,
AS_VIEW_END_LAYER,
// BDirectWindow/BWindowScreen codes
AS_DIRECT_WINDOW_GET_SYNC_DATA,

View File

@ -1,9 +1,10 @@
/*
* Copyright 2006-2007 Haiku, Inc. All rights reserved.
* Copyright 2006-2015 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stefano Ceccherini, burton666@libero.it
* Julian Harnath, <julian.harnath@rwth-achen.de>
*/
#ifndef _PICTURE_DATA_WRITER_H
#define _PICTURE_DATA_WRITER_H
@ -17,6 +18,7 @@
#include <stack>
class Layer;
class BPositionIO;
class BRegion;
@ -91,6 +93,8 @@ public:
status_t WriteDrawPicture(const BPoint& where,
const int32& token);
status_t WriteBlendLayer(Layer* layer);
protected:
// throw a status_t on error
void BeginOp(const int16& op);

View File

@ -52,10 +52,11 @@ enum {
B_PIC_SET_FONT_BPP = 0x0388,
B_PIC_SET_FONT_FACE = 0x0389,
B_PIC_SET_TRANSFORM = 0x0390,
B_PIC_BLEND_LAYER = 0x0391
};
const static uint32 kOpsTableSize = 49;
const static uint32 kOpsTableSize = 50;
#endif

View File

@ -1,9 +1,10 @@
/*
* Copyright 2006-2009 Haiku, Inc. All rights reserved.
* Copyright 2006-2015 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stefano Ceccherini, stefano.ceccherini@gmail.com
* Julian Harnath, <julian.harnath@rwth-achen.de>
*/
#include <PictureDataWriter.h>
@ -641,6 +642,21 @@ PictureDataWriter::WritePopState()
}
status_t
PictureDataWriter::WriteBlendLayer(Layer* layer)
{
try {
BeginOp(B_PIC_BLEND_LAYER);
Write<Layer*>(layer);
EndOp();
} catch (status_t& status) {
return status;
}
return B_OK;
}
// private
void
PictureDataWriter::BeginOp(const int16& op)

View File

@ -1,11 +1,12 @@
/*
* Copyright 2001-2007, Haiku Inc.
* Copyright 2001-2015, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Marc Flerackers (mflerackers@androme.be)
* Stefano Ceccherini (stefano.ceccherini@gmail.com)
* Marcus Overhagen (marcus@overhagen.de)
* Julian Harnath (julian.harnath@rwth-aachen.de)
*/
/** PicturePlayer is used to play picture data. */
@ -23,6 +24,9 @@
using BPrivate::PicturePlayer;
class Layer;
typedef void (*fnc)(void*);
typedef void (*fnc_BPoint)(void*, BPoint);
typedef void (*fnc_BPointBPoint)(void*, BPoint, BPoint);
@ -47,6 +51,7 @@ typedef void (*fnc_DrawPixels)(void *, BRect, BRect, int32, int32, int32,
typedef void (*fnc_DrawPicture)(void *, BPoint, int32);
typedef void (*fnc_BShape)(void*, BShape*);
typedef void (*fnc_BAffineTransform)(void*, BAffineTransform);
typedef void (*fnc_Layer)(void*, const Layer*);
static void
@ -160,7 +165,7 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData)
(void *)nop, (void *)nop, (void *)nop, (void *)nop,
(void *)nop, (void *)nop, (void *)nop, (void *)nop,
(void *)nop, (void *)nop, (void *)nop, (void *)nop,
(void *)nop
(void *)nop, (void *)nop
};
if ((uint32)tableEntries < kOpsTableSize) {
@ -546,6 +551,13 @@ PicturePlayer::Play(void **callBackTable, int32 tableEntries, void *userData)
break;
}
case B_PIC_BLEND_LAYER:
{
((fnc_Layer)functionTable[49])(userData,
*reinterpret_cast<Layer* const*>(data));
break;
}
default:
break;
}

View File

@ -7,6 +7,7 @@
* Axel Dörfler, axeld@pinc-software.de
* Adrian Oanca, adioanca@cotty.iren.ro
* Ingo Weinhold. ingo_weinhold@gmx.de
* Julian Harnath, julian.harnath@rwth-aachen.de
*/
@ -3933,6 +3934,27 @@ BView::DrawPictureAsync(const char* filename, long offset, BPoint where)
}
void
BView::BeginLayer(uint8 opacity)
{
if (_CheckOwnerLockAndSwitchCurrent()) {
fOwner->fLink->StartMessage(AS_VIEW_BEGIN_LAYER);
fOwner->fLink->Attach<uint8>(opacity);
_FlushIfNotInTransaction();
}
}
void
BView::EndLayer()
{
if (_CheckOwnerLockAndSwitchCurrent()) {
fOwner->fLink->StartMessage(AS_VIEW_END_LAYER);
_FlushIfNotInTransaction();
}
}
void
BView::Invalidate(BRect invalRect)
{
@ -5225,7 +5247,7 @@ BView::_ClipToPicture(BPicture* picture, BPoint where, bool invert, bool sync)
if (picture == NULL) {
fOwner->fLink->StartMessage(AS_VIEW_CLIP_TO_PICTURE);
fOwner->fLink->Attach<int32>(-1);
// NOTE: No need to sync here, since the -1 token cannot
// become invalid on the server.
} else {
@ -5240,7 +5262,7 @@ BView::_ClipToPicture(BPicture* picture, BPoint where, bool invert, bool sync)
// the client creates BPictures on the stack, these BPictures may
// have issued a AS_DELETE_PICTURE command to the ServerApp when Draw()
// goes out of scope, and the command is processed earlier in the
// ServerApp thread than the AS_VIEW_CLIP_TO_PICTURE command in the
// ServerApp thread than the AS_VIEW_CLIP_TO_PICTURE command in the
// ServerWindow thread, which will then have the result that no
// ServerPicture is found of the token.
if (sync)

View File

@ -19,8 +19,10 @@
#include <Region.h>
#include "AlphaMask.h"
#include "DrawingEngine.h"
#include "DrawState.h"
#include "Layer.h"
#if __GNUC__ >= 3
@ -218,6 +220,46 @@ Canvas::ScreenToPenTransform() const GCC_2_NRV(transform)
}
void
Canvas::BlendLayer(Layer* layer)
{
UtilityBitmap* layerBitmap = layer->RenderToBitmap(this);
if (layerBitmap == NULL)
return;
BRect destination = layerBitmap->Bounds();
destination.OffsetBy(layer->LeftTopOffset());
LocalToScreenTransform().Apply(&destination);
PushState();
fDrawState->SetDrawingMode(B_OP_ALPHA);
fDrawState->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
fDrawState->SetTransformEnabled(false);
AlphaMask* mask = new AlphaMask(layer->Opacity());
if (mask == NULL) {
layerBitmap->ReleaseReference();
return;
}
SetAlphaMask(mask);
mask->ReleaseReference();
ResyncDrawState();
GetDrawingEngine()->DrawBitmap(layerBitmap, layerBitmap->Bounds(),
destination, 0);
fDrawState->SetTransformEnabled(true);
PopState();
ResyncDrawState();
layerBitmap->ReleaseReference();
layer->ReleaseReference();
}
// #pragma mark - OffscreenCanvas

View File

@ -27,6 +27,7 @@ class DrawingEngine;
class DrawState;
class IntPoint;
class IntRect;
class Layer;
class ServerPicture;
@ -61,6 +62,8 @@ public:
SimpleTransform PenToLocalTransform() const;
SimpleTransform ScreenToPenTransform() const;
void BlendLayer(Layer* layer);
virtual DrawingEngine* GetDrawingEngine() const = 0;
virtual ServerPicture* GetPicture(int32 token) const = 0;
virtual void RebuildClipping(bool deep) = 0;

View File

@ -67,6 +67,7 @@ Server app_server :
InputManager.cpp
IntPoint.cpp
IntRect.cpp
Layer.cpp
MessageLooper.cpp
MultiLocker.cpp
OffscreenServerWindow.cpp

216
src/servers/app/Layer.cpp Normal file
View File

@ -0,0 +1,216 @@
/*
* Copyright 2015 Julian Harnath <julian.harnath@rwth-aachen.de>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "Layer.h"
#include "AlphaMask.h"
#include "BitmapHWInterface.h"
#include "DrawingEngine.h"
#include "DrawState.h"
#include "IntRect.h"
#include "PictureBoundingBoxPlayer.h"
#include "ServerBitmap.h"
#include "View.h"
class LayerCanvas : public Canvas {
public:
LayerCanvas(DrawingEngine* drawingEngine, DrawState* drawState)
:
Canvas(),
fDrawingEngine(drawingEngine)
{
delete fDrawState;
fDrawState = drawState;
}
virtual DrawingEngine* GetDrawingEngine() const
{
return fDrawingEngine;
}
virtual ServerPicture* GetPicture(int32 token) const
{
return NULL;
}
virtual void RebuildClipping(bool)
{
}
virtual void ResyncDrawState()
{
fDrawingEngine->SetDrawState(fDrawState);
}
protected:
virtual void _LocalToScreenTransform(SimpleTransform&) const
{
}
virtual void _ScreenToLocalTransform(SimpleTransform&) const
{
}
private:
DrawingEngine* fDrawingEngine;
};
Layer::Layer(uint8 opacity)
:
fOpacity(opacity),
fLeftTopOffset(0, 0)
{
}
Layer::~Layer()
{
}
void
Layer::PushLayer(Layer* layer)
{
PushPicture(layer);
}
Layer*
Layer::PopLayer()
{
Layer* const previousLayer = static_cast<Layer*>(PopPicture());
if (previousLayer != NULL)
previousLayer->ReleaseReference();
return previousLayer;
}
UtilityBitmap*
Layer::RenderToBitmap(Canvas* canvas)
{
BRect boundingBox = _DetermineBoundingBox(canvas);
if (!boundingBox.IsValid())
return NULL;
fLeftTopOffset = boundingBox.LeftTop();
UtilityBitmap* const layerBitmap = _AllocateBitmap(boundingBox);
if (layerBitmap == NULL)
return NULL;
BitmapHWInterface layerInterface(layerBitmap);
DrawingEngine* const layerEngine = layerInterface.CreateDrawingEngine();
if (layerEngine == NULL) {
layerBitmap->ReleaseReference();
return NULL;
}
layerEngine->SetRendererOffset(boundingBox.left, boundingBox.top);
// Drawing commands of the layer's picture use coordinates in the
// coordinate space of the underlying canvas. The coordinate origin
// of the layer bitmap is at boundingBox.LeftTop(). So all the drawing
// from the picture needs to be offset to be moved into the bitmap.
// We use a low-level offsetting via the AGG renderer here because the
// offset needs to be processed independently, after all other
// transforms, even after the BAffineTransforms (which are processed in
// Painter), to prevent this origin from being further transformed by
// e.g. scaling.
LayerCanvas layerCanvas(layerEngine, canvas->CurrentState());
AlphaMask* const mask = layerCanvas.GetAlphaMask();
BPoint oldOffset;
if (mask != NULL) {
// Move alpha mask to bitmap origin
oldOffset = mask->Update(BPoint(0, 0));
}
canvas->CurrentState()->SetDrawingMode(B_OP_ALPHA);
canvas->CurrentState()->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
layerCanvas.ResyncDrawState();
// Apply state to the new drawing engine of the layer canvas
if (layerEngine->LockParallelAccess()) {
const BRegion region(boundingBox);
layerEngine->ConstrainClippingRegion(&region);
// Draw recorded picture into bitmap
Play(&layerCanvas);
layerEngine->UnlockParallelAccess();
}
if (mask != NULL) {
// Move alpha mask back to its old position
// Note: this needs to be adapted if setting alpha masks is
// implemented as BPicture command (the mask now might be a different
// one than before).
mask->Update(oldOffset);
layerCanvas.ResyncDrawState();
}
canvas->SetDrawState(layerCanvas.CurrentState());
// Update state in canvas (the top-of-stack state could be a different
// state instance now, if the picture commands contained push/pop
// commands)
delete layerEngine;
return layerBitmap;
}
IntPoint
Layer::LeftTopOffset() const
{
return fLeftTopOffset;
}
uint8
Layer::Opacity() const
{
return fOpacity;
}
BRect
Layer::_DetermineBoundingBox(Canvas* canvas)
{
BRect boundingBox;
PictureBoundingBoxPlayer::Play(this, canvas->CurrentState(), &boundingBox);
if (!boundingBox.IsValid())
return boundingBox;
// Round up and add an additional 2 pixels on the bottom/right to
// compensate for the various types of rounding used in Painter.
boundingBox.left = floorf(boundingBox.left);
boundingBox.right = ceilf(boundingBox.right) + 2;
boundingBox.top = floorf(boundingBox.top);
boundingBox.bottom = ceilf(boundingBox.bottom) + 2;
// TODO: for optimization, crop the bounding box to the underlying
// view bounds here
return boundingBox;
}
UtilityBitmap*
Layer::_AllocateBitmap(const BRect& bounds)
{
UtilityBitmap* const layerBitmap = new(std::nothrow) UtilityBitmap(bounds,
B_RGBA32, 0);
if (layerBitmap == NULL)
return NULL;
if (!layerBitmap->IsValid()) {
delete layerBitmap;
return NULL;
}
memset(layerBitmap->Bits(), 0, layerBitmap->BitsLength());
return layerBitmap;
}

42
src/servers/app/Layer.h Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright 2015 Julian Harnath <julian.harnath@rwth-aachen.de>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef LAYER_H
#define LAYER_H
#include "ServerPicture.h"
#include "IntPoint.h"
class AlphaMask;
class Canvas;
class UtilityBitmap;
class Layer : public ServerPicture {
public:
Layer(uint8 opacity);
virtual ~Layer();
void PushLayer(Layer* layer);
Layer* PopLayer();
UtilityBitmap* RenderToBitmap(Canvas* canvas);
IntPoint LeftTopOffset() const;
uint8 Opacity() const;
private:
BRect _DetermineBoundingBox(Canvas* canvas);
UtilityBitmap* _AllocateBitmap(const BRect& bounds);
private:
uint8 fOpacity;
IntPoint fLeftTopOffset;
};
#endif // LAYER_H

View File

@ -16,6 +16,7 @@
#include "DrawState.h"
#include "FontManager.h"
#include "Layer.h"
#include "ServerApp.h"
#include "ServerBitmap.h"
#include "ServerFont.h"
@ -704,6 +705,18 @@ set_transform(BoundingBoxState* state, BAffineTransform transform)
}
static void
determine_bounds_nested_layer(BoundingBoxState* state, Layer* layer)
{
TRACE_BB("%p nested layer\n", state);
BRect boundingBox;
PictureBoundingBoxPlayer::Play(layer, state->GetDrawState(), &boundingBox);
if (boundingBox.IsValid())
state->IncludeRect(boundingBox);
}
const static void* kTableEntries[] = {
(const void*)nop, // 0
(const void*)move_pen_by,
@ -753,7 +766,8 @@ const static void* kTableEntries[] = {
(const void*)nop, // 45
(const void*)set_font_face,
(const void*)set_blending_mode,
(const void*)set_transform // 48
(const void*)set_transform,
(const void*)determine_bounds_nested_layer // 49
};

View File

@ -18,6 +18,7 @@
#include "DrawingEngine.h"
#include "DrawState.h"
#include "FontManager.h"
#include "Layer.h"
#include "ServerApp.h"
#include "ServerBitmap.h"
#include "ServerFont.h"
@ -784,6 +785,13 @@ set_transform(Canvas* canvas, BAffineTransform transform)
}
static void
blend_layer(Canvas* canvas, Layer* layer)
{
canvas->BlendLayer(layer);
}
static void
reserved()
{
@ -839,7 +847,8 @@ const static void* kTableEntries[] = {
(const void*)reserved, // 45
(const void*)set_font_face,
(const void*)set_blending_mode,
(const void*)set_transform // 48
(const void*)set_transform,
(const void*)blend_layer // 49
};

View File

@ -1,10 +1,11 @@
/*
* Copyright 2001-2010, Haiku.
* Copyright 2001-2015, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Stefano Ceccherini <stefano.ceccherini@gmail.com>
* Julian Harnath <julian.harnath@rwth-aachen.de>
*/
#ifndef SERVER_PICTURE_H
#define SERVER_PICTURE_H
@ -35,7 +36,7 @@ public:
ServerPicture(const ServerPicture& other);
ServerPicture(const char* fileName,
int32 offset);
~ServerPicture();
virtual ~ServerPicture();
int32 Token() { return fToken; }
bool SetOwner(ServerApp* owner);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2010, Haiku.
* Copyright 2001-2015, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -11,6 +11,7 @@
* Artur Wyszynski <harakash@gmail.com>
* Philippe Saint-Pierre <stpere@gmail.com>
* Brecht Machiels <brecht@mos6581.org>
* Julian Harnath <julian.harnath@rwth-aachen.de>
*/
@ -61,6 +62,7 @@
#include "DrawingEngine.h"
#include "DrawState.h"
#include "HWInterface.h"
#include "Layer.h"
#include "Overlay.h"
#include "ProfileMessageSupport.h"
#include "RenderingBuffer.h"
@ -2184,6 +2186,21 @@ fDesktop->LockSingleWindow();
break;
}
case AS_VIEW_BEGIN_LAYER:
{
DTRACE(("ServerWindow %s: Message AS_VIEW_BEGIN_LAYER\n",
Title()));
uint8 opacity;
link.Read<uint8>(&opacity);
Layer* layer = new(std::nothrow) Layer(opacity);
if (layer == NULL)
break;
fCurrentView->SetPicture(layer);
break;
}
default:
_DispatchViewDrawingMessage(code, link);
break;
@ -2922,6 +2939,15 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
break;
}
case AS_VIEW_END_LAYER:
{
DTRACE(("ServerWindow %s: Message AS_VIEW_END_LAYER\n",
Title()));
fCurrentView->BlendAllLayers();
fCurrentView->SetPicture(NULL);
break;
}
default:
BString codeString;
string_for_message_code(code, codeString);
@ -2983,6 +3009,11 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link)
int8 drawingMode;
link.Read<int8>(&drawingMode);
if (dynamic_cast<Layer*>(picture) != NULL) {
// drawing mode changes not allowed in layers
break;
}
picture->WriteSetDrawingMode((drawing_mode)drawingMode);
fCurrentView->CurrentState()->SetDrawingMode(
@ -3416,6 +3447,42 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver& link)
fLink.Flush();
return true;
}
case AS_VIEW_BEGIN_LAYER:
{
uint8 opacity;
link.Read<uint8>(&opacity);
Layer* layer = dynamic_cast<Layer*>(picture);
if (layer == NULL)
break;
Layer* nextLayer = new(std::nothrow) Layer(opacity);
if (nextLayer == NULL)
break;
nextLayer->PushLayer(layer);
fCurrentView->SetPicture(nextLayer);
break;
}
case AS_VIEW_END_LAYER:
{
Layer* layer = dynamic_cast<Layer*>(picture);
if (layer == NULL)
break;
Layer* previousLayer = layer->PopLayer();
if (previousLayer == NULL) {
// End last layer
return false;
}
fCurrentView->SetPicture(previousLayer);
previousLayer->WriteBlendLayer(layer);
break;
}
/*
case AS_VIEW_SET_BLENDING_MODE:
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2014, Haiku, Inc.
* Copyright (c) 2001-2015, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
@ -9,6 +9,7 @@
* Stephan Aßmus <superstippi@gmx.de>
* Marcus Overhagen <marcus@overhagen.de>
* Adrien Destugues <pulkomandy@pulkomandy.tk
* Julian Harnath <julian.harnath@rwth-aachen.de>
*/
#include "View.h"
@ -19,6 +20,7 @@
#include "Desktop.h"
#include "DrawingEngine.h"
#include "DrawState.h"
#include "Layer.h"
#include "Overlay.h"
#include "ServerApp.h"
#include "ServerBitmap.h"
@ -27,6 +29,7 @@
#include "ServerWindow.h"
#include "Window.h"
#include "BitmapHWInterface.h"
#include "drawing_support.h"
#include <List.h>
@ -972,6 +975,18 @@ View::SetPicture(ServerPicture* picture)
}
void
View::BlendAllLayers()
{
if (fPicture == NULL)
return;
Layer* layer = dynamic_cast<Layer*>(fPicture);
if (layer == NULL)
return;
BlendLayer(layer);
}
void
View::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
BRegion* windowContentClipping, bool deep)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2014, Haiku, Inc.
* Copyright (c) 2001-2015, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
@ -9,6 +9,7 @@
* Stephan Aßmus <superstippi@gmx.de>
* Marcus Overhagen <marcus@overhagen.de>
* Adrien Destugues <pulkomandy@pulkomandy.tk>
* Julian Harnath <julian.harnath@rwth-aachen.de>
*/
#ifndef VIEW_H
#define VIEW_H
@ -156,6 +157,8 @@ public:
ServerPicture* Picture() const
{ return fPicture; }
void BlendAllLayers();
// for background clearing
virtual void Draw(DrawingEngine* drawingEngine,
BRegion* effectiveClipping,

View File

@ -154,6 +154,7 @@ SharedLibrary libtestappserver.so :
BitmapHWInterface.cpp
Canvas.cpp
DesktopSettings.cpp
Layer.cpp
OffscreenServerWindow.cpp
OffscreenWindow.cpp
PictureBoundingBoxPlayer.cpp