app_server: add pixel alpha composite solid mode
* Same concept as the previously exisiting drawing mode implementations for e.g. pixel alpha overlay mode: when pattern is solid, provide a separate mode implementation which does no unnecessary pattern pixel lookups. This provides a considerable speedup in composite mode when no stipple pattern is used.
This commit is contained in:
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2005, Stephan Aßmus <[email protected]>
|
||||||
|
* Copyright 2015, Julian Harnath <[email protected]>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* DrawingMode implementing B_OP_ALPHA in "Pixel Composite" mode on B_RGBA32.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DRAWING_MODE_ALPHA_PC_SOLID_H
|
||||||
|
#define DRAWING_MODE_ALPHA_PC_SOLID_H
|
||||||
|
|
||||||
|
#include "DrawingMode.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define BLEND_ALPHA_PC(d, r, g, b, a) \
|
||||||
|
{ \
|
||||||
|
BLEND_COMPOSITE16(d, r, g, b, a); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ASSIGN_ALPHA_PC(d, r, g, b) \
|
||||||
|
{ \
|
||||||
|
d[0] = (b); \
|
||||||
|
d[1] = (g); \
|
||||||
|
d[2] = (r); \
|
||||||
|
d[3] = 255; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
blend_pixel_alpha_pc_solid(int x, int y, const color_type& color, uint8 cover,
|
||||||
|
agg_buffer* buffer, const PatternHandler*)
|
||||||
|
{
|
||||||
|
uint8* p = buffer->row_ptr(y) + (x << 2);
|
||||||
|
uint16 alpha = color.a * cover;
|
||||||
|
if (alpha == 255 * 255) {
|
||||||
|
ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
|
||||||
|
} else {
|
||||||
|
BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
blend_hline_alpha_pc_solid(int x, int y, unsigned len,
|
||||||
|
const color_type& color, uint8 cover,
|
||||||
|
agg_buffer* buffer, const PatternHandler*)
|
||||||
|
{
|
||||||
|
uint8* p = buffer->row_ptr(y) + (x << 2);
|
||||||
|
uint16 alpha = color.a * cover;
|
||||||
|
if (alpha == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (alpha == 255 * 255) {
|
||||||
|
do {
|
||||||
|
ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
|
||||||
|
p += 4;
|
||||||
|
} while(--len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
|
||||||
|
p += 4;
|
||||||
|
} while(--len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
blend_solid_hspan_alpha_pc_solid(int x, int y, unsigned len,
|
||||||
|
const color_type& color, const uint8* covers,
|
||||||
|
agg_buffer* buffer, const PatternHandler*)
|
||||||
|
{
|
||||||
|
uint8* p = buffer->row_ptr(y) + (x << 2);
|
||||||
|
do {
|
||||||
|
uint16 alpha = color.a * *covers;
|
||||||
|
if (alpha) {
|
||||||
|
if(alpha == 255 * 255) {
|
||||||
|
ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
|
||||||
|
} else {
|
||||||
|
BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
covers++;
|
||||||
|
p += 4;
|
||||||
|
} while(--len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
blend_solid_vspan_alpha_pc_solid(int x, int y, unsigned len,
|
||||||
|
const color_type& color, const uint8* covers,
|
||||||
|
agg_buffer* buffer, const PatternHandler*)
|
||||||
|
{
|
||||||
|
uint8* p = buffer->row_ptr(y) + (x << 2);
|
||||||
|
do {
|
||||||
|
uint16 alpha = color.a * *covers;
|
||||||
|
if (alpha) {
|
||||||
|
if (alpha == 255 * 255) {
|
||||||
|
ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
|
||||||
|
} else {
|
||||||
|
BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
covers++;
|
||||||
|
p += buffer->stride();
|
||||||
|
} while(--len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
blend_color_hspan_alpha_pc_solid(int x, int y, unsigned len,
|
||||||
|
const color_type* colors,
|
||||||
|
const uint8* covers, uint8 cover,
|
||||||
|
agg_buffer* buffer, const PatternHandler*)
|
||||||
|
{
|
||||||
|
uint8* p = buffer->row_ptr(y) + (x << 2);
|
||||||
|
if (covers) {
|
||||||
|
// non-solid opacity
|
||||||
|
do {
|
||||||
|
uint16 alpha = colors->a * *covers;
|
||||||
|
if (alpha) {
|
||||||
|
if (alpha == 255 * 255) {
|
||||||
|
ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b);
|
||||||
|
} else {
|
||||||
|
BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
covers++;
|
||||||
|
p += 4;
|
||||||
|
++colors;
|
||||||
|
} while(--len);
|
||||||
|
} else {
|
||||||
|
// solid full opcacity
|
||||||
|
uint16 alpha = colors->a * cover;
|
||||||
|
if (alpha == 255 * 255) {
|
||||||
|
do {
|
||||||
|
ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b);
|
||||||
|
p += 4;
|
||||||
|
++colors;
|
||||||
|
} while(--len);
|
||||||
|
// solid partial opacity
|
||||||
|
} else if (alpha) {
|
||||||
|
do {
|
||||||
|
BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha);
|
||||||
|
p += 4;
|
||||||
|
++colors;
|
||||||
|
} while(--len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DRAWING_MODE_ALPHA_PC_SOLID_H
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "DrawingModeAlphaCO.h"
|
#include "DrawingModeAlphaCO.h"
|
||||||
#include "DrawingModeAlphaCOSolid.h"
|
#include "DrawingModeAlphaCOSolid.h"
|
||||||
#include "DrawingModeAlphaPC.h"
|
#include "DrawingModeAlphaPC.h"
|
||||||
|
#include "DrawingModeAlphaPCSolid.h"
|
||||||
#include "DrawingModeAlphaPO.h"
|
#include "DrawingModeAlphaPO.h"
|
||||||
#include "DrawingModeAlphaPOSolid.h"
|
#include "DrawingModeAlphaPOSolid.h"
|
||||||
#include "DrawingModeBlend.h"
|
#include "DrawingModeBlend.h"
|
||||||
@@ -211,7 +212,7 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
|
|||||||
case B_OP_COPY:
|
case B_OP_COPY:
|
||||||
if (text) {
|
if (text) {
|
||||||
fBlendPixel = blend_pixel_copy_text;
|
fBlendPixel = blend_pixel_copy_text;
|
||||||
fBlendHLine = blend_hline_copy_text;
|
fBlendHLine = blend_hline_copy_text;
|
||||||
fBlendSolidHSpanSubpix = blend_solid_hspan_copy_text_subpix;
|
fBlendSolidHSpanSubpix = blend_solid_hspan_copy_text_subpix;
|
||||||
fBlendSolidHSpan = blend_solid_hspan_copy_text;
|
fBlendSolidHSpan = blend_solid_hspan_copy_text;
|
||||||
fBlendSolidVSpan = blend_solid_vspan_copy_text;
|
fBlendSolidVSpan = blend_solid_vspan_copy_text;
|
||||||
@@ -327,12 +328,21 @@ PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
|
|||||||
}
|
}
|
||||||
fBlendColorHSpan = blend_color_hspan_alpha_po;
|
fBlendColorHSpan = blend_color_hspan_alpha_po;
|
||||||
} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
|
} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
|
||||||
fBlendPixel = blend_pixel_alpha_pc;
|
if (fPatternHandler->IsSolid()) {
|
||||||
fBlendHLine = blend_hline_alpha_pc;
|
fBlendPixel = blend_pixel_alpha_pc_solid;
|
||||||
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix;
|
fBlendHLine = blend_hline_alpha_pc_solid;
|
||||||
fBlendSolidHSpan = blend_solid_hspan_alpha_pc;
|
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix;
|
||||||
fBlendSolidVSpan = blend_solid_vspan_alpha_pc;
|
fBlendSolidHSpan = blend_solid_hspan_alpha_pc_solid;
|
||||||
fBlendColorHSpan = blend_color_hspan_alpha_pc;
|
fBlendSolidVSpan = blend_solid_vspan_alpha_pc_solid;
|
||||||
|
fBlendColorHSpan = blend_color_hspan_alpha_pc_solid;
|
||||||
|
} else {
|
||||||
|
fBlendPixel = blend_pixel_alpha_pc;
|
||||||
|
fBlendHLine = blend_hline_alpha_pc;
|
||||||
|
fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix;
|
||||||
|
fBlendSolidHSpan = blend_solid_hspan_alpha_pc;
|
||||||
|
fBlendSolidVSpan = blend_solid_vspan_alpha_pc;
|
||||||
|
fBlendColorHSpan = blend_color_hspan_alpha_pc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user