app_server: Some cleanup of the new clipping code.

* Fixed some coding style issues and use regular pointers like everywhere
   else in app_server code.
 * Moved _RenderPicture() from View to AlphaMask.
This commit is contained in:
Stephan Aßmus
2014-01-28 22:10:33 +01:00
parent 69437993a2
commit a01eaea74b
4 changed files with 106 additions and 103 deletions
+81 -11
View File
@@ -1,16 +1,22 @@
/*
* Copyright 2014, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <[email protected]>
*/
#include "AlphaMask.h"
#include "BitmapHWInterface.h"
#include "BitmapManager.h"
#include "DrawingEngine.h"
#include "ServerBitmap.h"
#include "View.h"
AlphaMask::AlphaMask(View& view, ServerPicture& picture, bool inverse,
AlphaMask::AlphaMask(View* view, ServerPicture* picture, bool inverse,
BPoint origin)
:
fPicture(picture),
@@ -22,13 +28,13 @@ AlphaMask::AlphaMask(View& view, ServerPicture& picture, bool inverse,
fCachedMask(),
fScanline(fCachedMask)
{
fPicture.AcquireReference();
fPicture->AcquireReference();
}
AlphaMask::~AlphaMask()
{
fPicture.ReleaseReference();
fPicture->ReleaseReference();
if (fCachedBitmap)
fCachedBitmap->ReleaseReference();
}
@@ -37,23 +43,87 @@ AlphaMask::~AlphaMask()
scanline_unpacked_masked_type*
AlphaMask::Generate()
{
// If rendering the picture fails, we will draw without any clipping.
ServerBitmap* bitmap = fView._RenderPicture(&fPicture, fInverse);
if (!bitmap)
return NULL;
// if (fCachedBitmap != NULL) {
// // TODO: See if cached bitmap can actually be used. Don't use it
// // when view scrolling offset has changed, for example. Generate()
// // could be passed a current offset
// return &fScanline;
// }
// FIXME actually use the cached bitmap whenever possible, instead of
// rendering the BPicture again and again.
if (fCachedBitmap)
if (fCachedBitmap != NULL)
fCachedBitmap->ReleaseReference();
// If rendering the picture fails, we will draw without any clipping.
ServerBitmap* bitmap = _RenderPicture(fPicture, fInverse);
if (bitmap == NULL) {
fCachedBitmap = NULL;
fBuffer.attach(NULL, 0, 0, 0);
return NULL;
}
fCachedBitmap = bitmap;
fBuffer.attach(fCachedBitmap->Bits(), fCachedBitmap->Width(),
fCachedBitmap->Height(), fCachedBitmap->BytesPerRow());
BPoint offset(B_ORIGIN);
fView.ConvertToScreen(&offset);
fView->ConvertToScreen(&offset);
fCachedMask.attach(fBuffer, offset.x + fOrigin.x, offset.y + fOrigin.y,
fInverse ? 255 : 0);
return &fScanline;
}
ServerBitmap*
AlphaMask::_RenderPicture(ServerPicture* picture, bool inverse) const
{
BRect bounds(fView->Bounds());
// TODO: Only the alpha channel is relevant, but there is no B_ALPHA8
// color space, so we use 300% more memory than needed.
UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(bounds, B_RGBA32,
0);
if (bitmap == NULL)
return NULL;
// Clear the bitmap with the transparent color
memset(bitmap->Bits(), 0, bitmap->BitsLength());
// Render the picture to the bitmap
BitmapHWInterface interface(bitmap);
DrawingEngine* engine = interface.CreateDrawingEngine();
if (engine == NULL) {
delete bitmap;
return NULL;
}
// Copy the current state of the client view, so we draw with the right
// font, color and everything
engine->SetDrawState(fView->CurrentState());
OffscreenContext context(engine);
if (engine->LockParallelAccess()) {
// FIXME ConstrainClippingRegion docs says passing NULL disables
// all clipping. This doesn't work and will crash in Painter.
BRegion clipping;
clipping.Include(bounds);
engine->ConstrainClippingRegion(&clipping);
picture->Play(&context);
engine->UnlockParallelAccess();
}
delete engine;
if (!inverse)
return bitmap;
// Compute the inverse of our bitmap. There probably is a better way.
uint32 size = bitmap->BitsLength();
uint8* bits = (uint8*)bitmap->Bits();
for(uint32 i = 0; i < size; i++)
bits[i] = 255 - bits[i];
return bitmap;
}
+22 -18
View File
@@ -17,26 +17,30 @@
class ServerBitmap;
class AlphaMask
{
public:
AlphaMask(View& view,
ServerPicture& mask, bool inverse,
BPoint origin);
~AlphaMask();
scanline_unpacked_masked_type* Generate();
class AlphaMask {
public:
AlphaMask(View* view, ServerPicture* mask,
bool inverse, BPoint origin);
~AlphaMask();
private:
ServerPicture& fPicture;
const bool fInverse;
const BPoint fOrigin;
View& fView;
scanline_unpacked_masked_type* Generate();
ServerBitmap* fCachedBitmap;
agg::rendering_buffer fBuffer;
agg::clipped_alpha_mask fCachedMask;
scanline_unpacked_masked_type fScanline;
private:
ServerBitmap* _RenderPicture(ServerPicture* picture,
bool inverse) const;
private:
ServerPicture* fPicture;
const bool fInverse;
BPoint fOrigin;
View* fView;
ServerBitmap* fCachedBitmap;
agg::rendering_buffer fBuffer;
agg::clipped_alpha_mask fCachedMask;
scanline_unpacked_masked_type fScanline;
};
#endif
#endif // ALPHA_MASK_H
+1 -69
View File
@@ -16,8 +16,6 @@
#include <stdio.h>
#include "AlphaMask.h"
#include "BitmapHWInterface.h"
#include "BitmapManager.h"
#include "Desktop.h"
#include "DrawingEngine.h"
#include "DrawState.h"
@@ -1596,79 +1594,13 @@ View::SetAlphaMask(ServerPicture* picture, bool inverse, BPoint origin)
delete fAlphaMask;
if (picture != NULL) {
fAlphaMask = new(std::nothrow) AlphaMask(*this, *picture, inverse,
fAlphaMask = new(std::nothrow) AlphaMask(this, picture, inverse,
origin);
} else
fAlphaMask = NULL;
}
ServerBitmap*
View::_RenderPicture(ServerPicture* picture, bool inverse)
{
BRect bounds(Bounds());
// TODO: Only the alpha channel is relevant, but there is no B_ALPHA8
// color space, so we use 300% more memory than needed.
UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(bounds, B_RGBA32,
0);
if (bitmap == NULL)
return NULL;
#if 0
/*
* TODO stippi says we could use OffscreenWindow to do this, but there
* doesn't seem to be a way to create a View without a BView on
* application side (the constructor wants a token).
* This would be better, as it would avoid the DrawingContext abstraction
* above View and OffscreenContext and allow for inlining more methods.
*/
OffscreenWindow window(bitmap, "ClipToPicture", Window());
View view(bounds, IntPoint(0, 0), "ClipToPicture");
window->SetTopView(view);
#endif
// Clear the bitmap with the transparent color
memset(bitmap->Bits(), 0, bitmap->BitsLength());
// Render the picture to the bitmap
BitmapHWInterface interface(bitmap);
DrawingEngine* engine = interface.CreateDrawingEngine();
if (engine == NULL) {
delete bitmap;
return NULL;
}
// Copy the current state of the client view, so we draw with the right
// font, color and everything
engine->SetDrawState(CurrentState());
OffscreenContext context(engine);
if (engine->LockParallelAccess())
{
// FIXME ConstrainClippingRegion docs says passing NULL disables
// all clipping. This doesn't work and will crash in Painter.
BRegion clipping;
clipping.Include(bounds);
engine->ConstrainClippingRegion(&clipping);
picture->Play(&context);
engine->UnlockParallelAccess();
}
delete engine;
if (!inverse)
return bitmap;
// Compute the inverse of our bitmap. There probably is a better way.
uint32 size = bitmap->BitsLength();
uint8* bits = (uint8*)bitmap->Bits();
for(uint32 i = 0; i < size; i++)
bits[i] = 255 - bits[i];
return bitmap;
}
BRegion&
View::_ScreenClipping(BRegion* windowContentClipping, bool force) const
{
+2 -5
View File
@@ -39,7 +39,7 @@ class ServerPicture;
class BGradient;
class View: public DrawingContext {
public:
public:
View(IntRect frame, IntPoint scrollingOffset,
const char* name, int32 token,
uint32 resizeMode, uint32 flags);
@@ -232,10 +232,7 @@ class View: public DrawingContext {
int32 level = 0);
#endif
protected:
friend class AlphaMask;
ServerBitmap* _RenderPicture(ServerPicture* picture,
bool inverse);
protected:
BRegion& _ScreenClipping(BRegion* windowContentClipping,
bool force = false) const;
void _MoveScreenClipping(int32 x, int32 y,