From c676b8fcc6956a243efcf28332ce3b520bf75835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Tue, 13 Dec 2005 20:18:13 +0000 Subject: [PATCH] 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 --- .../Painter/drawing_modes/DrawingMode.h | 5 + .../drawing_modes/DrawingModeFactory.cpp | 8 +- .../drawing_modes/DrawingModeFactory.h | 1 + .../Painter/drawing_modes/DrawingModeOver.h | 27 ++- .../drawing_modes/DrawingModeOverSolid.h | 187 ++++++++++++++++++ 5 files changed, 213 insertions(+), 15 deletions(-) create mode 100644 src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h index f3f46c724a..d5a68b93cb 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingMode.h @@ -17,6 +17,11 @@ class PatternHandler; +union pixel32 { + uint32 data32; + uint8 data8[4]; +}; + // BLEND // // This macro assumes source alpha in range 0..255 and diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeFactory.cpp b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeFactory.cpp index 15538db38f..a23416386c 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeFactory.cpp +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeFactory.cpp @@ -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; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeFactory.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeFactory.h index 190fe19ea8..0375002728 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeFactory.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeFactory.h @@ -25,6 +25,7 @@ class DrawingModeFactory { bool solid = false); private: DrawingMode* fDrawingModeBGRA32Over; + DrawingMode* fDrawingModeBGRA32OverSolid; DrawingMode* fDrawingModeBGRA32Erase; DrawingMode* fDrawingModeBGRA32Invert; DrawingMode* fDrawingModeBGRA32Select; diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h index 191fcaa264..f634e2c8e9 100644 --- a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOver.h @@ -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); diff --git a/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h new file mode 100644 index 0000000000..08a7765aba --- /dev/null +++ b/src/servers/app/drawing/Painter/drawing_modes/DrawingModeOverSolid.h @@ -0,0 +1,187 @@ +/* + * Copyright 2005, Stephan Aßmus . 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 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 DrawingModeRGBA32OverSolid; +typedef DrawingModeOverSolid DrawingModeARGB32OverSolid; +typedef DrawingModeOverSolid DrawingModeABGR32OverSolid; +typedef DrawingModeOverSolid DrawingModeBGRA32OverSolid; + +#endif // DRAWING_MODE_OVER_H +