now has a special version of B_OP_OVER for solid patterns as well, accelerated the alpha blending for B_OP_OVER.... these are the first shy steps of rewriting the drawing mode stuff... :-)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15532 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-12-13 20:18:13 +00:00
parent 2a867ee674
commit c676b8fcc6
5 changed files with 213 additions and 15 deletions
@@ -17,6 +17,11 @@
class PatternHandler;
union pixel32 {
uint32 data32;
uint8 data8[4];
};
// BLEND
//
// This macro assumes source alpha in range 0..255 and
@@ -22,6 +22,7 @@
#include "DrawingModeMax.h"
#include "DrawingModeMin.h"
#include "DrawingModeOver.h"
#include "DrawingModeOverSolid.h"
#include "DrawingModeSelect.h"
#include "DrawingModeSubtract.h"
@@ -30,6 +31,7 @@
// constructor
DrawingModeFactory::DrawingModeFactory()
: fDrawingModeBGRA32Over(new DrawingModeBGRA32Over()),
fDrawingModeBGRA32OverSolid(new DrawingModeBGRA32OverSolid()),
fDrawingModeBGRA32Erase(new DrawingModeBGRA32Erase()),
fDrawingModeBGRA32Invert(new DrawingModeBGRA32Invert()),
fDrawingModeBGRA32Select(new DrawingModeBGRA32Select()),
@@ -51,6 +53,7 @@ DrawingModeFactory::DrawingModeFactory()
DrawingModeFactory::~DrawingModeFactory()
{
delete fDrawingModeBGRA32Over;
delete fDrawingModeBGRA32OverSolid;
delete fDrawingModeBGRA32Erase;
delete fDrawingModeBGRA32Invert;
delete fDrawingModeBGRA32Select;
@@ -78,7 +81,10 @@ DrawingModeFactory::DrawingModeFor(drawing_mode mode,
// these drawing modes discard source pixels
// which have the current low color
case B_OP_OVER:
return fDrawingModeBGRA32Over;
if (solid)
return fDrawingModeBGRA32OverSolid;
else
return fDrawingModeBGRA32Over;
break;
case B_OP_ERASE:
return fDrawingModeBGRA32Erase;
@@ -25,6 +25,7 @@ class DrawingModeFactory {
bool solid = false);
private:
DrawingMode* fDrawingModeBGRA32Over;
DrawingMode* fDrawingModeBGRA32OverSolid;
DrawingMode* fDrawingModeBGRA32Erase;
DrawingMode* fDrawingModeBGRA32Invert;
DrawingMode* fDrawingModeBGRA32Select;
@@ -12,9 +12,14 @@
#include "DrawingMode.h"
// BLEND_OVER
#define BLEND_OVER(d1, d2, d3, da, s1, s2, s3, a) \
#define BLEND_OVER(d, s1, s2, s3, a) \
{ \
BLEND(d1, d2, d3, da, s1, s2, s3, a); \
pixel32 _p; \
_p.data32 = *(uint32*)d; \
d[0] = (((((s3) - _p.data8[0]) * (a)) + (_p.data8[0] << 8)) >> 8); \
d[1] = (((((s2) - _p.data8[1]) * (a)) + (_p.data8[1] << 8)) >> 8); \
d[2] = (((((s1) - _p.data8[2]) * (a)) + (_p.data8[2] << 8)) >> 8); \
d[3] = 255; \
}
// ASSIGN_OVER
@@ -46,8 +51,7 @@ class DrawingModeOver : public DrawingMode {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
} else {
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, cover);
BLEND_OVER(p, color.red, color.green, color.blue, cover);
}
}
}
@@ -76,8 +80,7 @@ class DrawingModeOver : public DrawingMode {
rgb_color color = fPatternHandler->HighColor().GetColor32();
do {
if (fPatternHandler->IsHighColor(x, y)) {
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, cover);
BLEND_OVER(p, color.red, color.green, color.blue, cover);
}
x++;
p += 4;
@@ -105,8 +108,7 @@ printf("DrawingModeOver::blend_vline()\n");
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
} else {
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, *covers);
BLEND_OVER(p, color.red, color.green, color.blue, *covers);
}
}
}
@@ -131,8 +133,7 @@ printf("DrawingModeOver::blend_vline()\n");
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue);
} else {
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
color.red, color.green, color.blue, *covers);
BLEND_OVER(p, color.red, color.green, color.blue, *covers);
}
}
}
@@ -159,8 +160,7 @@ if (*covers && (colors->a & 0xff)) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b);
} else {
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b, *covers);
BLEND_OVER(p, colors->r, colors->g, colors->b, *covers);
}
}
covers++;
@@ -181,8 +181,7 @@ if (colors->a & 0xff) {
// solid partial opacity
} else if (cover) {
do {
BLEND_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b, cover);
BLEND_OVER(p, colors->r, colors->g, colors->b, cover);
p += 4;
++colors;
} while(--len);
@@ -0,0 +1,187 @@
/*
* Copyright 2005, Stephan Aßmus <[email protected]>. All rights reserved.
* Distributed under the terms of the MIT License.
*
* DrawingMode implementing B_OP_OVER on B_RGBA32.
*
*/
#ifndef DRAWING_MODE_OVER_SOLID_H
#define DRAWING_MODE_OVER_SOLID_H
#include "DrawingModeOver.h"
template<class Order>
class DrawingModeOverSolid : public DrawingMode {
public:
// constructor
DrawingModeOverSolid()
: DrawingMode()
{
}
// blend_pixel
virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover)
{
if (fPatternHandler->IsSolidLow())
return;
uint8* p = fBuffer->row(y) + (x << 2);
if (cover == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
c.r, c.g, c.b);
} else {
BLEND_OVER(p, c.r, c.g, c.b, cover);
}
}
// blend_hline
virtual void blend_hline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
if (fPatternHandler->IsSolidLow())
return;
if(cover == 255) {
uint32 v;
uint8* p8 = (uint8*)&v;
p8[Order::R] = (uint8)c.r;
p8[Order::G] = (uint8)c.g;
p8[Order::B] = (uint8)c.b;
p8[Order::A] = 255;
uint32* p32 = (uint32*)(fBuffer->row(y)) + x;
do {
*p32 = v;
p32++;
x++;
} while(--len);
} else {
uint8* p = fBuffer->row(y) + (x << 2);
do {
BLEND_OVER(p, c.r, c.g, c.b, cover);
x++;
p += 4;
} while(--len);
}
}
// blend_vline
virtual void blend_vline(int x, int y, unsigned len,
const color_type& c, uint8 cover)
{
printf("DrawingModeOver::blend_vline()\n");
}
// blend_solid_hspan
virtual void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
if (fPatternHandler->IsSolidLow())
return;
uint8* p = fBuffer->row(y) + (x << 2);
do {
if (*covers) {
if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
c.r, c.g, c.b);
} else {
BLEND_OVER(p, c.r, c.g, c.b, *covers);
}
}
covers++;
p += 4;
x++;
} while(--len);
}
// blend_solid_vspan
virtual void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const uint8* covers)
{
if (fPatternHandler->IsSolidLow())
return;
uint8* p = fBuffer->row(y) + (x << 2);
do {
if (*covers) {
if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
c.r, c.g, c.b);
} else {
BLEND_OVER(p, c.r, c.g, c.b, *covers);
}
}
covers++;
p += fBuffer->stride();
y++;
} while(--len);
}
// blend_color_hspan
virtual void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
uint8* p = fBuffer->row(y) + (x << 2);
if (covers) {
// non-solid opacity
do {
// if (*covers) {
if (*covers && (colors->a & 0xff)) {
if (*covers == 255) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b);
} else {
BLEND_OVER(p, colors->r, colors->g, colors->b, *covers);
}
}
covers++;
p += 4;
++colors;
} while(--len);
} else {
// solid full opcacity
if (cover == 255) {
do {
if (colors->a & 0xff) {
ASSIGN_OVER(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
colors->r, colors->g, colors->b);
}
p += 4;
++colors;
} while(--len);
// solid partial opacity
} else if (cover) {
do {
BLEND_OVER(p, colors->r, colors->g, colors->b, cover);
p += 4;
++colors;
} while(--len);
}
}
}
// blend_color_vspan
virtual void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const uint8* covers,
uint8 cover)
{
printf("DrawingModeOver::blend_color_vspan()\n");
}
};
typedef DrawingModeOverSolid<agg::order_rgba32> DrawingModeRGBA32OverSolid;
typedef DrawingModeOverSolid<agg::order_argb32> DrawingModeARGB32OverSolid;
typedef DrawingModeOverSolid<agg::order_abgr32> DrawingModeABGR32OverSolid;
typedef DrawingModeOverSolid<agg::order_bgra32> DrawingModeBGRA32OverSolid;
#endif // DRAWING_MODE_OVER_H