mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-15 12:34:30 +00:00
sw_engine: optimizing the masking feature
replaced 32-bit operations with 8-bit operations for masking buffers. We might need a grasycale image support for applying 1-byte channel masking input(Picture). Some of masking implementation are disabled by this reason. Also, I don't expecct it's necessary for the thorvg now.
This commit is contained in:
parent
624b275628
commit
21413b1872
5 changed files with 405 additions and 316 deletions
|
@ -47,27 +47,34 @@ void tvgDrawCmds(tvg::Canvas* canvas)
|
||||||
{
|
{
|
||||||
//Shape + Shape Mask Add
|
//Shape + Shape Mask Add
|
||||||
auto shape = tvg::Shape::gen();
|
auto shape = tvg::Shape::gen();
|
||||||
shape->appendCircle(125, 100, 50, 50);
|
shape->appendCircle(125, 100, 150, 150);
|
||||||
shape->fill(255, 255, 255);
|
shape->fill(255, 255, 255);
|
||||||
|
|
||||||
auto mask = tvg::Shape::gen();
|
auto mask = tvg::Shape::gen();
|
||||||
mask->appendCircle(175, 100, 50, 50);
|
mask->appendCircle(125, 100, 50, 50);
|
||||||
mask->fill(255, 255, 255);
|
mask->fill(255, 255, 255);
|
||||||
shape->composite(std::move(mask), tvg::CompositeMethod::AddMask);
|
|
||||||
|
|
||||||
|
auto add = tvg::Shape::gen();
|
||||||
|
add->appendCircle(175, 100, 50, 50);
|
||||||
|
add->fill(255, 255, 255);
|
||||||
|
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
|
||||||
|
shape->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(shape));
|
canvas->push(std::move(shape));
|
||||||
|
|
||||||
//Shape + Shape Mask Subtract
|
//Shape + Shape Mask Subtract
|
||||||
auto shape2 = tvg::Shape::gen();
|
auto shape2 = tvg::Shape::gen();
|
||||||
shape2->appendCircle(375, 100, 50, 50);
|
shape2->appendCircle(375, 100, 150, 150);
|
||||||
shape2->fill(255, 255, 255, 127);
|
shape2->fill(255, 255, 255, 255);
|
||||||
|
|
||||||
auto mask2 = tvg::Shape::gen();
|
auto mask2 = tvg::Shape::gen();
|
||||||
mask2->appendCircle(400, 100, 50, 50);
|
mask2->appendCircle(375, 100, 50, 50);
|
||||||
mask2->fill(255, 255, 255);
|
mask2->fill(255, 255, 255, 127);
|
||||||
|
|
||||||
shape2->composite(std::move(mask2), tvg::CompositeMethod::SubtractMask);
|
|
||||||
|
|
||||||
|
auto sub = tvg::Shape::gen();
|
||||||
|
sub->appendCircle(400, 100, 50, 50);
|
||||||
|
sub->fill(255, 255, 255);
|
||||||
|
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
|
||||||
|
shape2->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(shape2));
|
canvas->push(std::move(shape2));
|
||||||
|
|
||||||
//Shape + Shape Mask Intersect
|
//Shape + Shape Mask Intersect
|
||||||
|
@ -76,125 +83,160 @@ void tvgDrawCmds(tvg::Canvas* canvas)
|
||||||
shape3->fill(255, 255, 255, 127);
|
shape3->fill(255, 255, 255, 127);
|
||||||
|
|
||||||
auto mask3 = tvg::Shape::gen();
|
auto mask3 = tvg::Shape::gen();
|
||||||
mask3->appendCircle(650, 100, 50, 50);
|
mask3->appendCircle(625, 100, 50, 50);
|
||||||
mask3->fill(255, 255, 255);
|
mask3->fill(255, 255, 255, 127);
|
||||||
shape3->composite(std::move(mask3), tvg::CompositeMethod::IntersectMask);
|
|
||||||
|
|
||||||
|
auto inter = tvg::Shape::gen();
|
||||||
|
inter->appendCircle(650, 100, 50, 50);
|
||||||
|
inter->fill(255, 255, 255);
|
||||||
|
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
|
||||||
|
shape3->composite(std::move(mask3), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(shape3));
|
canvas->push(std::move(shape3));
|
||||||
|
|
||||||
//Shape + Shape Mask Difference
|
//Shape + Shape Mask Difference
|
||||||
auto shape4 = tvg::Shape::gen();
|
auto shape4 = tvg::Shape::gen();
|
||||||
shape4->appendCircle(875, 100, 50, 50);
|
shape4->appendCircle(875, 100, 150, 150);
|
||||||
shape4->fill(255, 255, 255);
|
shape4->fill(255, 255, 255);
|
||||||
|
|
||||||
auto mask4 = tvg::Shape::gen();
|
auto mask4 = tvg::Shape::gen();
|
||||||
mask4->appendCircle(900, 100, 50, 50);
|
mask4->appendCircle(875, 100, 50, 50);
|
||||||
mask4->fill(255, 255, 255);
|
mask4->fill(255, 255, 255);
|
||||||
shape4->composite(std::move(mask4), tvg::CompositeMethod::DifferenceMask);
|
|
||||||
|
|
||||||
|
auto diff = tvg::Shape::gen();
|
||||||
|
diff->appendCircle(900, 100, 50, 50);
|
||||||
|
diff->fill(255, 255, 255);
|
||||||
|
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
|
||||||
|
shape4->composite(std::move(mask4), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(shape4));
|
canvas->push(std::move(shape4));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
//Shape + Image Mask Add
|
//Shape + Shape Mask Add
|
||||||
auto shape = tvg::Shape::gen();
|
auto shape = tvg::Shape::gen();
|
||||||
shape->appendCircle(150, 250, 50, 50);
|
shape->appendCircle(125, 300, 100, 100);
|
||||||
shape->fill(255, 255, 255);
|
|
||||||
|
|
||||||
auto mask = tvg::Picture::gen();
|
|
||||||
if (mask->load(data, 200, 300, true) != tvg::Result::Success) return;
|
|
||||||
mask->translate(100, 250);
|
|
||||||
mask->scale(0.5f);
|
|
||||||
shape->composite(std::move(mask), tvg::CompositeMethod::AddMask);
|
|
||||||
canvas->push(std::move(shape));
|
|
||||||
|
|
||||||
//Shape + Image Mask Subtract
|
|
||||||
auto shape2 = tvg::Shape::gen();
|
|
||||||
shape2->appendCircle(400, 250, 50, 50);
|
|
||||||
shape2->fill(255, 255, 255, 127);
|
|
||||||
|
|
||||||
auto mask2 = tvg::Picture::gen();
|
|
||||||
if (mask2->load(data, 200, 300, true) != tvg::Result::Success) return;
|
|
||||||
mask2->translate(350, 250);
|
|
||||||
mask2->scale(0.5f);
|
|
||||||
shape2->composite(std::move(mask2), tvg::CompositeMethod::SubtractMask);
|
|
||||||
|
|
||||||
canvas->push(std::move(shape2));
|
|
||||||
|
|
||||||
//Shape + Image Mask Intersect
|
|
||||||
auto shape3 = tvg::Shape::gen();
|
|
||||||
shape3->appendCircle(650, 250, 50, 50);
|
|
||||||
shape3->fill(255, 255, 255, 127);
|
|
||||||
|
|
||||||
auto mask3 = tvg::Picture::gen();
|
|
||||||
if (mask3->load(data, 200, 300, true) != tvg::Result::Success) return;
|
|
||||||
mask3->translate(600, 250);
|
|
||||||
mask3->scale(0.5f);
|
|
||||||
shape3->composite(std::move(mask3), tvg::CompositeMethod::IntersectMask);
|
|
||||||
|
|
||||||
canvas->push(std::move(shape3));
|
|
||||||
|
|
||||||
//Shape + Image Mask Difference
|
|
||||||
auto shape4 = tvg::Shape::gen();
|
|
||||||
shape4->appendCircle(900, 250, 50, 50);
|
|
||||||
shape4->fill(255, 255, 255);
|
|
||||||
|
|
||||||
auto mask4 = tvg::Picture::gen();
|
|
||||||
if (mask4->load(data, 200, 300, true) != tvg::Result::Success) return;
|
|
||||||
mask4->translate(850, 250);
|
|
||||||
mask4->scale(0.5f);
|
|
||||||
shape4->composite(std::move(mask4), tvg::CompositeMethod::DifferenceMask);
|
|
||||||
|
|
||||||
canvas->push(std::move(shape4));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
//Rect + Rect Mask Add
|
|
||||||
auto shape = tvg::Shape::gen();
|
|
||||||
shape->appendRect(75, 500, 100, 100);
|
|
||||||
shape->fill(255, 255, 255);
|
shape->fill(255, 255, 255);
|
||||||
|
|
||||||
auto mask = tvg::Shape::gen();
|
auto mask = tvg::Shape::gen();
|
||||||
mask->appendRect(125, 450, 100, 100);
|
mask->appendCircle(125, 300, 50, 50);
|
||||||
mask->fill(255, 255, 255);
|
mask->fill(255, 255, 255);
|
||||||
shape->composite(std::move(mask), tvg::CompositeMethod::AddMask);
|
|
||||||
|
|
||||||
|
auto add = tvg::Shape::gen();
|
||||||
|
add->appendCircle(175, 300, 50, 50);
|
||||||
|
add->fill(255, 255, 255);
|
||||||
|
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
|
||||||
|
shape->composite(std::move(mask), tvg::CompositeMethod::InvAlphaMask);
|
||||||
|
canvas->push(std::move(shape));
|
||||||
|
|
||||||
|
//Shape + Shape Mask Subtract
|
||||||
|
auto shape2 = tvg::Shape::gen();
|
||||||
|
shape2->appendCircle(375, 300, 100, 100);
|
||||||
|
shape2->fill(255, 255, 255, 255);
|
||||||
|
|
||||||
|
auto mask2 = tvg::Shape::gen();
|
||||||
|
mask2->appendCircle(375, 300, 50, 50);
|
||||||
|
mask2->fill(255, 255, 255, 127);
|
||||||
|
|
||||||
|
auto sub = tvg::Shape::gen();
|
||||||
|
sub->appendCircle(400, 300, 50, 50);
|
||||||
|
sub->fill(255, 255, 255);
|
||||||
|
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
|
||||||
|
shape2->composite(std::move(mask2), tvg::CompositeMethod::InvAlphaMask);
|
||||||
|
canvas->push(std::move(shape2));
|
||||||
|
|
||||||
|
//Shape + Shape Mask Intersect
|
||||||
|
auto shape3 = tvg::Shape::gen();
|
||||||
|
shape3->appendCircle(625, 300, 100, 100);
|
||||||
|
shape3->fill(255, 255, 255, 127);
|
||||||
|
|
||||||
|
auto mask3 = tvg::Shape::gen();
|
||||||
|
mask3->appendCircle(625, 300, 50, 50);
|
||||||
|
mask3->fill(255, 255, 255, 127);
|
||||||
|
|
||||||
|
auto inter = tvg::Shape::gen();
|
||||||
|
inter->appendCircle(650, 300, 50, 50);
|
||||||
|
inter->fill(255, 255, 255);
|
||||||
|
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
|
||||||
|
shape3->composite(std::move(mask3), tvg::CompositeMethod::InvAlphaMask);
|
||||||
|
canvas->push(std::move(shape3));
|
||||||
|
|
||||||
|
//Shape + Shape Mask Difference
|
||||||
|
auto shape4 = tvg::Shape::gen();
|
||||||
|
shape4->appendCircle(875, 300, 100, 100);
|
||||||
|
shape4->fill(255, 255, 255);
|
||||||
|
|
||||||
|
auto mask4 = tvg::Shape::gen();
|
||||||
|
mask4->appendCircle(875, 300, 50, 50);
|
||||||
|
mask4->fill(255, 255, 255);
|
||||||
|
|
||||||
|
auto diff = tvg::Shape::gen();
|
||||||
|
diff->appendCircle(900, 300, 50, 50);
|
||||||
|
diff->fill(255, 255, 255);
|
||||||
|
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
|
||||||
|
shape4->composite(std::move(mask4), tvg::CompositeMethod::InvAlphaMask);
|
||||||
|
canvas->push(std::move(shape4));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
//Rect + Rect Mask Add
|
||||||
|
auto shape = tvg::Shape::gen();
|
||||||
|
shape->appendRect(75, 450, 150, 150);
|
||||||
|
shape->fill(255, 255, 255);
|
||||||
|
|
||||||
|
auto mask = tvg::Shape::gen();
|
||||||
|
mask->appendRect(75, 500, 100, 100);
|
||||||
|
mask->fill(255, 255, 255);
|
||||||
|
|
||||||
|
auto add = tvg::Shape::gen();
|
||||||
|
add->appendRect(125, 450, 100, 100);
|
||||||
|
add->fill(255, 255, 255);
|
||||||
|
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
|
||||||
|
shape->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(shape));
|
canvas->push(std::move(shape));
|
||||||
|
|
||||||
//Rect + Rect Mask Subtract
|
//Rect + Rect Mask Subtract
|
||||||
auto shape2 = tvg::Shape::gen();
|
auto shape2 = tvg::Shape::gen();
|
||||||
shape2->appendRect(325, 500, 100, 100);
|
shape2->appendRect(325, 450, 150, 150);
|
||||||
shape2->fill(255, 255, 255, 127);
|
shape2->fill(255, 255, 255);
|
||||||
|
|
||||||
auto mask2 = tvg::Shape::gen();
|
auto mask2 = tvg::Shape::gen();
|
||||||
mask2->appendRect(375, 450, 100, 100);
|
mask2->appendRect(325, 500, 100, 100);
|
||||||
mask2->fill(255, 255, 255);
|
mask2->fill(255, 255, 255, 127);
|
||||||
shape2->composite(std::move(mask2), tvg::CompositeMethod::SubtractMask);
|
|
||||||
|
|
||||||
|
auto sub = tvg::Shape::gen();
|
||||||
|
sub->appendRect(375, 450, 100, 100);
|
||||||
|
sub->fill(255, 255, 255);
|
||||||
|
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
|
||||||
|
shape2->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(shape2));
|
canvas->push(std::move(shape2));
|
||||||
|
|
||||||
//Rect + Rect Mask Intersect
|
//Rect + Rect Mask Intersect
|
||||||
auto shape3 = tvg::Shape::gen();
|
auto shape3 = tvg::Shape::gen();
|
||||||
shape3->appendRect(575, 500, 100, 100);
|
shape3->appendRect(575, 450, 150, 150);
|
||||||
shape3->fill(255, 255, 255, 127);
|
shape3->fill(255, 255, 255);
|
||||||
|
|
||||||
auto mask3 = tvg::Shape::gen();
|
auto mask3 = tvg::Shape::gen();
|
||||||
mask3->appendRect(625, 450, 100, 100);
|
mask3->appendRect(575, 500, 100, 100);
|
||||||
mask3->fill(255, 255, 255);
|
mask3->fill(255, 255, 255, 127);
|
||||||
shape3->composite(std::move(mask3), tvg::CompositeMethod::IntersectMask);
|
|
||||||
|
|
||||||
|
auto inter = tvg::Shape::gen();
|
||||||
|
inter->appendRect(625, 450, 100, 100);
|
||||||
|
inter->fill(255, 255, 255);
|
||||||
|
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
|
||||||
|
shape3->composite(std::move(mask3), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(shape3));
|
canvas->push(std::move(shape3));
|
||||||
|
|
||||||
//Rect + Rect Mask Difference
|
//Rect + Rect Mask Difference
|
||||||
auto shape4 = tvg::Shape::gen();
|
auto shape4 = tvg::Shape::gen();
|
||||||
shape4->appendRect(825, 500, 100, 100);
|
shape4->appendRect(825, 450, 150, 150);
|
||||||
shape4->fill(255, 255, 255);
|
shape4->fill(255, 255, 255);
|
||||||
|
|
||||||
auto mask4 = tvg::Shape::gen();
|
auto mask4 = tvg::Shape::gen();
|
||||||
mask4->appendRect(875, 450, 100, 100);
|
mask4->appendRect(825, 500, 100, 100);
|
||||||
mask4->fill(255, 255, 255);
|
mask4->fill(255, 255, 255);
|
||||||
shape4->composite(std::move(mask4), tvg::CompositeMethod::DifferenceMask);
|
|
||||||
|
|
||||||
|
auto diff = tvg::Shape::gen();
|
||||||
|
diff->appendRect(875, 450, 100, 100);
|
||||||
|
diff->fill(255, 255, 255);
|
||||||
|
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
|
||||||
|
shape4->composite(std::move(mask4), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(shape4));
|
canvas->push(std::move(shape4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +251,12 @@ void tvgDrawCmds(tvg::Canvas* canvas)
|
||||||
auto mask = tvg::Shape::gen();
|
auto mask = tvg::Shape::gen();
|
||||||
mask->appendCircle(125, 700, 50, 50);
|
mask->appendCircle(125, 700, 50, 50);
|
||||||
mask->fill(255, 255, 255);
|
mask->fill(255, 255, 255);
|
||||||
image->composite(std::move(mask), tvg::CompositeMethod::AddMask);
|
|
||||||
|
auto add = tvg::Shape::gen();
|
||||||
|
add->appendCircle(150, 750, 50, 50);
|
||||||
|
add->fill(255, 255, 255);
|
||||||
|
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
|
||||||
|
image->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(image));
|
canvas->push(std::move(image));
|
||||||
|
|
||||||
//Transformed Image + Shape Mask Subtract
|
//Transformed Image + Shape Mask Subtract
|
||||||
|
@ -218,12 +265,16 @@ void tvgDrawCmds(tvg::Canvas* canvas)
|
||||||
image2->translate(400, 650);
|
image2->translate(400, 650);
|
||||||
image2->scale(0.5f);
|
image2->scale(0.5f);
|
||||||
image2->rotate(45);
|
image2->rotate(45);
|
||||||
image2->opacity(127);
|
|
||||||
|
|
||||||
auto mask2 = tvg::Shape::gen();
|
auto mask2 = tvg::Shape::gen();
|
||||||
mask2->appendCircle(375, 700, 50, 50);
|
mask2->appendCircle(375, 700, 50, 50);
|
||||||
mask2->fill(255, 255, 255);
|
mask2->fill(255, 255, 255, 127);
|
||||||
image2->composite(std::move(mask2), tvg::CompositeMethod::SubtractMask);
|
|
||||||
|
auto sub = tvg::Shape::gen();
|
||||||
|
sub->appendCircle(400, 750, 50, 50);
|
||||||
|
sub->fill(255, 255, 255);
|
||||||
|
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
|
||||||
|
image2->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(image2));
|
canvas->push(std::move(image2));
|
||||||
|
|
||||||
//Transformed Image + Shape Mask Intersect
|
//Transformed Image + Shape Mask Intersect
|
||||||
|
@ -232,12 +283,16 @@ void tvgDrawCmds(tvg::Canvas* canvas)
|
||||||
image3->translate(650, 650);
|
image3->translate(650, 650);
|
||||||
image3->scale(0.5f);
|
image3->scale(0.5f);
|
||||||
image3->rotate(45);
|
image3->rotate(45);
|
||||||
image3->opacity(127);
|
|
||||||
|
|
||||||
auto mask3 = tvg::Shape::gen();
|
auto mask3 = tvg::Shape::gen();
|
||||||
mask3->appendCircle(625, 700, 50, 50);
|
mask3->appendCircle(625, 700, 50, 50);
|
||||||
mask3->fill(255, 255, 255);
|
mask3->fill(255, 255, 255, 127);
|
||||||
image3->composite(std::move(mask3), tvg::CompositeMethod::IntersectMask);
|
|
||||||
|
auto inter = tvg::Shape::gen();
|
||||||
|
inter->appendCircle(650, 750, 50, 50);
|
||||||
|
inter->fill(255, 255, 255, 127);
|
||||||
|
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
|
||||||
|
image3->composite(std::move(mask3), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(image3));
|
canvas->push(std::move(image3));
|
||||||
|
|
||||||
//Transformed Image + Shape Mask Difference
|
//Transformed Image + Shape Mask Difference
|
||||||
|
@ -250,91 +305,87 @@ void tvgDrawCmds(tvg::Canvas* canvas)
|
||||||
auto mask4 = tvg::Shape::gen();
|
auto mask4 = tvg::Shape::gen();
|
||||||
mask4->appendCircle(875, 700, 50, 50);
|
mask4->appendCircle(875, 700, 50, 50);
|
||||||
mask4->fill(255, 255, 255);
|
mask4->fill(255, 255, 255);
|
||||||
image4->composite(std::move(mask4), tvg::CompositeMethod::DifferenceMask);
|
|
||||||
|
auto diff = tvg::Shape::gen();
|
||||||
|
diff->appendCircle(900, 750, 50, 50);
|
||||||
|
diff->fill(255, 255, 255);
|
||||||
|
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
|
||||||
|
image4->composite(std::move(mask4), tvg::CompositeMethod::AlphaMask);
|
||||||
canvas->push(std::move(image4));
|
canvas->push(std::move(image4));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
//Gradient Color Stops
|
//Transformed Image + Shape Mask Add
|
||||||
tvg::Fill::ColorStop colorStops[2];
|
auto image = tvg::Picture::gen();
|
||||||
colorStops[0] = {0, 255, 0, 0, 255};
|
if (image->load(data, 200, 300, true) != tvg::Result::Success) return;
|
||||||
colorStops[1] = {1, 255, 255, 255, 255};
|
image->translate(150, 850);
|
||||||
|
image->scale(0.5f);
|
||||||
//Shape + Shape Mask Add
|
image->rotate(45);
|
||||||
auto shape = tvg::Shape::gen();
|
|
||||||
shape->appendRect(75, 850, 100, 100, 10, 10);
|
|
||||||
|
|
||||||
//LinearGradient
|
|
||||||
auto fill = tvg::LinearGradient::gen();
|
|
||||||
fill->linear(75, 850, 175, 950);
|
|
||||||
fill->colorStops(colorStops, 2);
|
|
||||||
shape->fill(std::move(fill));
|
|
||||||
|
|
||||||
auto mask = tvg::Shape::gen();
|
auto mask = tvg::Shape::gen();
|
||||||
mask->appendCircle(175, 900, 50, 50);
|
mask->appendCircle(125, 900, 50, 50);
|
||||||
mask->fill(255, 255, 255);
|
mask->fill(255, 255, 255);
|
||||||
shape->composite(std::move(mask), tvg::CompositeMethod::AddMask);
|
|
||||||
|
|
||||||
canvas->push(std::move(shape));
|
auto add = tvg::Shape::gen();
|
||||||
|
add->appendCircle(150, 950, 50, 50);
|
||||||
|
add->fill(255, 255, 255);
|
||||||
|
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
|
||||||
|
image->composite(std::move(mask), tvg::CompositeMethod::InvAlphaMask);
|
||||||
|
canvas->push(std::move(image));
|
||||||
|
|
||||||
//Shape + Shape Mask Subtract
|
//Transformed Image + Shape Mask Subtract
|
||||||
auto shape2 = tvg::Shape::gen();
|
auto image2 = tvg::Picture::gen();
|
||||||
shape2->appendRect(300, 850, 100, 100, 10, 10);
|
if (image2->load(data, 200, 300, true) != tvg::Result::Success) return;
|
||||||
|
image2->translate(400, 850);
|
||||||
//LinearGradient
|
image2->scale(0.5f);
|
||||||
auto fill2 = tvg::LinearGradient::gen();
|
image2->rotate(45);
|
||||||
fill2->linear(300, 850, 400, 950);
|
|
||||||
fill2->colorStops(colorStops, 2);
|
|
||||||
shape2->fill(std::move(fill2));
|
|
||||||
shape2->opacity(127);
|
|
||||||
|
|
||||||
auto mask2 = tvg::Shape::gen();
|
auto mask2 = tvg::Shape::gen();
|
||||||
mask2->appendCircle(400, 900, 50, 50);
|
mask2->appendCircle(375, 900, 50, 50);
|
||||||
mask2->fill(255, 255, 255);
|
mask2->fill(255, 255, 255, 127);
|
||||||
|
|
||||||
shape2->composite(std::move(mask2), tvg::CompositeMethod::SubtractMask);
|
auto sub = tvg::Shape::gen();
|
||||||
|
sub->appendCircle(400, 950, 50, 50);
|
||||||
|
sub->fill(255, 255, 255);
|
||||||
|
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
|
||||||
|
image2->composite(std::move(mask2), tvg::CompositeMethod::InvAlphaMask);
|
||||||
|
canvas->push(std::move(image2));
|
||||||
|
|
||||||
canvas->push(std::move(shape2));
|
//Transformed Image + Shape Mask Intersect
|
||||||
|
auto image3 = tvg::Picture::gen();
|
||||||
//Shape + Shape Mask Intersect
|
if (image3->load(data, 200, 300, true) != tvg::Result::Success) return;
|
||||||
auto shape3 = tvg::Shape::gen();
|
image3->translate(650, 850);
|
||||||
shape3->appendRect(550, 850, 100, 100, 10, 10);
|
image3->scale(0.5f);
|
||||||
|
image3->rotate(45);
|
||||||
//LinearGradient
|
|
||||||
auto fill3 = tvg::LinearGradient::gen();
|
|
||||||
fill3->linear(550, 850, 650, 950);
|
|
||||||
fill3->colorStops(colorStops, 2);
|
|
||||||
shape3->fill(std::move(fill3));
|
|
||||||
shape3->opacity(127);
|
|
||||||
|
|
||||||
auto mask3 = tvg::Shape::gen();
|
auto mask3 = tvg::Shape::gen();
|
||||||
mask3->appendCircle(650, 900, 50, 50);
|
mask3->appendCircle(625, 900, 50, 50);
|
||||||
mask3->fill(255, 255, 255);
|
mask3->fill(255, 255, 255, 127);
|
||||||
shape3->composite(std::move(mask3), tvg::CompositeMethod::IntersectMask);
|
|
||||||
|
|
||||||
canvas->push(std::move(shape3));
|
auto inter = tvg::Shape::gen();
|
||||||
|
inter->appendCircle(650, 950, 50, 50);
|
||||||
//Shape + Shape Mask Difference
|
inter->fill(255, 255, 255, 127);
|
||||||
auto shape4 = tvg::Shape::gen();
|
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
|
||||||
shape4->appendRect(800, 850, 100, 100, 10, 10);
|
image3->composite(std::move(mask3), tvg::CompositeMethod::InvAlphaMask);
|
||||||
shape4->fill(255, 255, 255);
|
canvas->push(std::move(image3));
|
||||||
|
|
||||||
//LinearGradient
|
|
||||||
auto fill4 = tvg::LinearGradient::gen();
|
|
||||||
fill4->linear(800, 850, 900, 950);
|
|
||||||
fill4->colorStops(colorStops, 2);
|
|
||||||
shape4->fill(std::move(fill4));
|
|
||||||
|
|
||||||
|
//Transformed Image + Shape Mask Difference
|
||||||
|
auto image4 = tvg::Picture::gen();
|
||||||
|
if (image4->load(data, 200, 300, true) != tvg::Result::Success) return;
|
||||||
|
image4->translate(900, 850);
|
||||||
|
image4->scale(0.5f);
|
||||||
|
image4->rotate(45);
|
||||||
|
|
||||||
auto mask4 = tvg::Shape::gen();
|
auto mask4 = tvg::Shape::gen();
|
||||||
mask4->appendCircle(900, 900, 50, 50);
|
mask4->appendCircle(875, 900, 50, 50);
|
||||||
mask4->fill(255, 255, 255);
|
mask4->fill(255, 255, 255);
|
||||||
shape4->composite(std::move(mask4), tvg::CompositeMethod::DifferenceMask);
|
|
||||||
|
|
||||||
canvas->push(std::move(shape4));
|
auto diff = tvg::Shape::gen();
|
||||||
|
diff->appendCircle(900, 950, 50, 50);
|
||||||
|
diff->fill(255, 255, 255);
|
||||||
|
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
|
||||||
|
image4->composite(std::move(mask4), tvg::CompositeMethod::InvAlphaMask);
|
||||||
|
canvas->push(std::move(image4));
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,7 @@ struct SwImage
|
||||||
bool scaled = false; //draw scaled image
|
bool scaled = false; //draw scaled image
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint8_t(*SwMask)(uint8_t s, uint8_t d, uint8_t a); //src, dst, alpha
|
||||||
typedef uint32_t(*SwBlender)(uint32_t s, uint32_t d, uint8_t a); //src, dst, alpha
|
typedef uint32_t(*SwBlender)(uint32_t s, uint32_t d, uint8_t a); //src, dst, alpha
|
||||||
typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join
|
typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join
|
||||||
typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha
|
typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha
|
||||||
|
@ -295,7 +296,7 @@ static inline uint32_t INTERPOLATE(uint32_t s, uint32_t d, uint8_t a)
|
||||||
|
|
||||||
static inline uint8_t INTERPOLATE8(uint8_t s, uint8_t d, uint8_t a)
|
static inline uint8_t INTERPOLATE8(uint8_t s, uint8_t d, uint8_t a)
|
||||||
{
|
{
|
||||||
return ((s * a + 0xff) >> 8) + ((d * ~a + 0xff) >> 8);
|
return (((s) * (a) + 0xff) >> 8) + (((d) * ~(a) + 0xff) >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SwCoord HALF_STROKE(float width)
|
static inline SwCoord HALF_STROKE(float width)
|
||||||
|
|
|
@ -85,9 +85,6 @@ struct FillRadial
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity = 255);
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint8_t _alpha(uint8_t* a)
|
static inline uint8_t _alpha(uint8_t* a)
|
||||||
{
|
{
|
||||||
return *a;
|
return *a;
|
||||||
|
@ -166,52 +163,54 @@ static inline bool _masking(const SwSurface* surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t _opMaskAdd(uint32_t s, uint32_t d, uint8_t a)
|
static inline uint8_t _opMaskAdd(uint8_t s, uint8_t d, uint8_t a)
|
||||||
{
|
{
|
||||||
return s + ALPHA_BLEND(d, a);
|
return s + MULTIPLY(d, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t _opMaskSubtract(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
static inline uint8_t _opMaskSubtract(uint8_t s, uint8_t d, TVG_UNUSED uint8_t a)
|
||||||
{
|
{
|
||||||
return ALPHA_BLEND(s, IA(d));
|
return MULTIPLY(s, 255 - d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t _opMaskIntersect(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
static inline uint8_t _opMaskIntersect(uint8_t s, uint8_t d, TVG_UNUSED uint8_t a)
|
||||||
{
|
{
|
||||||
return ALPHA_BLEND(s, A(d));
|
return MULTIPLY(s, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t _opMaskDifference(uint32_t s, uint32_t d, uint8_t a)
|
static inline uint8_t _opMaskDifference(uint8_t s, uint8_t d, uint8_t a)
|
||||||
{
|
{
|
||||||
return ALPHA_BLEND(s, IA(d)) + ALPHA_BLEND(d, a);
|
return MULTIPLY(s, 255 - d) + MULTIPLY(d, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t _opAMaskAdd(uint32_t s, uint32_t d, uint8_t a)
|
static inline uint8_t _opAMaskAdd(uint8_t s, uint8_t d, uint8_t a)
|
||||||
{
|
{
|
||||||
return INTERPOLATE(s, d, a);
|
return INTERPOLATE8(s, d, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t _opAMaskSubtract(TVG_UNUSED uint32_t s, uint32_t d, uint8_t a)
|
static inline uint8_t _opAMaskSubtract(TVG_UNUSED uint8_t s, uint8_t d, uint8_t a)
|
||||||
{
|
{
|
||||||
return ALPHA_BLEND(s, MULTIPLY(IA(d), a));
|
return s;
|
||||||
|
//return ALPHA_BLEND(s, MULTIPLY(IA(d), a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t _opAMaskDifference(uint32_t s, uint32_t d, uint8_t a)
|
static inline uint8_t _opAMaskDifference(uint8_t s, uint8_t d, uint8_t a)
|
||||||
{
|
{
|
||||||
auto t = ALPHA_BLEND(s, a);
|
auto t = MULTIPLY(s, a);
|
||||||
return ALPHA_BLEND(t, IA(d)) + ALPHA_BLEND(d, IA(t));
|
return MULTIPLY(t, 255 - d) + MULTIPLY(d, 255 - t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t _opAMaskIntersect(uint32_t s, uint32_t d, uint8_t a)
|
static inline uint8_t _opAMaskIntersect(uint8_t s, uint8_t d, uint8_t a)
|
||||||
{
|
{
|
||||||
return ALPHA_BLEND(s, MULTIPLY(A(d), a));
|
return s;
|
||||||
|
//return ALPHA_BLEND(s, MULTIPLY(A(d), a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -223,7 +222,7 @@ static inline bool _direct(CompositeMethod method)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline SwBlender _getMaskOp(CompositeMethod method)
|
static inline SwMask _getMaskOp(CompositeMethod method)
|
||||||
{
|
{
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case CompositeMethod::AddMask: return _opMaskAdd;
|
case CompositeMethod::AddMask: return _opMaskAdd;
|
||||||
|
@ -235,7 +234,7 @@ static inline SwBlender _getMaskOp(CompositeMethod method)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline SwBlender _getAMaskOp(CompositeMethod method)
|
static inline SwMask _getAMaskOp(CompositeMethod method)
|
||||||
{
|
{
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case CompositeMethod::AddMask: return _opAMaskAdd;
|
case CompositeMethod::AddMask: return _opAMaskAdd;
|
||||||
|
@ -247,6 +246,24 @@ static inline SwBlender _getAMaskOp(CompositeMethod method)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool _compositeMaskImage(SwSurface* surface, const SwImage* image, const SwBBox& region)
|
||||||
|
{
|
||||||
|
auto dbuffer = &surface->buf8[region.min.y * surface->stride + region.min.x];
|
||||||
|
auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
|
||||||
|
|
||||||
|
for (auto y = region.min.y; y < region.max.y; ++y) {
|
||||||
|
auto dst = dbuffer;
|
||||||
|
auto src = sbuffer;
|
||||||
|
for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) {
|
||||||
|
*dst = *src + MULTIPLY(*dst, ~*src);
|
||||||
|
}
|
||||||
|
dbuffer += surface->stride;
|
||||||
|
sbuffer += image->stride;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "tvgSwRasterTexmap.h"
|
#include "tvgSwRasterTexmap.h"
|
||||||
#include "tvgSwRasterC.h"
|
#include "tvgSwRasterC.h"
|
||||||
#include "tvgSwRasterAvx.h"
|
#include "tvgSwRasterAvx.h"
|
||||||
|
@ -316,40 +333,38 @@ static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t
|
||||||
/* Rect */
|
/* Rect */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static bool _rasterCompositeMaskedRect(SwSurface* surface, const SwBBox& region, SwBlender maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
static bool _rasterCompositeMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
{
|
{
|
||||||
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
||||||
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
||||||
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * surface->compositor->image.stride + region.min.x); //compositor buffer
|
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto color = surface->join(r, g, b, a);
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); //compositor buffer
|
||||||
auto ialpha = 255 - a;
|
auto ialpha = 255 - a;
|
||||||
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
auto cmp = cbuffer;
|
auto cmp = cbuffer;
|
||||||
for (uint32_t x = 0; x < w; ++x, ++cmp) {
|
for (uint32_t x = 0; x < w; ++x, ++cmp) {
|
||||||
*cmp = maskOp(color, *cmp, ialpha);
|
*cmp = maskOp(a, *cmp, ialpha);
|
||||||
}
|
}
|
||||||
cbuffer += cstride;
|
cbuffer += cstride;
|
||||||
}
|
}
|
||||||
return _rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, SwBlender maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
{
|
{
|
||||||
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
||||||
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
||||||
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * surface->compositor->image.stride + region.min.x); //compositor buffer
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x); //compositor buffer
|
||||||
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); //destination buffer
|
auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); //destination buffer
|
||||||
auto color = surface->join(r, g, b, a);
|
|
||||||
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
auto cmp = cbuffer;
|
auto cmp = cbuffer;
|
||||||
auto dst = dbuffer;
|
auto dst = dbuffer;
|
||||||
for (uint32_t x = 0; x < w; ++x, ++cmp, ++dst) {
|
for (uint32_t x = 0; x < w; ++x, ++cmp, ++dst) {
|
||||||
auto tmp = maskOp(color, *cmp, 0); //not use alpha.
|
auto tmp = maskOp(a, *cmp, 0); //not use alpha.
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
}
|
}
|
||||||
cbuffer += surface->compositor->image.stride;
|
cbuffer += surface->compositor->image.stride;
|
||||||
dbuffer += surface->stride;
|
dbuffer += surface->stride;
|
||||||
|
@ -360,13 +375,12 @@ static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, Sw
|
||||||
|
|
||||||
static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
{
|
{
|
||||||
//32bit channels composition
|
//8bit masking channels composition
|
||||||
if (surface->channelSize != sizeof(uint32_t)) return false;
|
if (surface->channelSize != sizeof(uint8_t)) return false;
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Masked(%d) Rect [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
TVGLOG("SW_ENGINE", "Masked(%d) Rect [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
||||||
|
|
||||||
auto maskOp = _getMaskOp(surface->compositor->method);
|
auto maskOp = _getMaskOp(surface->compositor->method);
|
||||||
|
|
||||||
if (_direct(surface->compositor->method)) return _rasterDirectMaskedRect(surface, region, maskOp, r, g, b, a);
|
if (_direct(surface->compositor->method)) return _rasterDirectMaskedRect(surface, region, maskOp, r, g, b, a);
|
||||||
else return _rasterCompositeMaskedRect(surface, region, maskOp, r, g, b, a);
|
else return _rasterCompositeMaskedRect(surface, region, maskOp, r, g, b, a);
|
||||||
return false;
|
return false;
|
||||||
|
@ -458,7 +472,7 @@ static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint8_t r
|
||||||
//8bits grayscale
|
//8bits grayscale
|
||||||
if (surface->channelSize == sizeof(uint8_t)) {
|
if (surface->channelSize == sizeof(uint8_t)) {
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
rasterGrayscale8(surface->buf8, 255, region.min.y * surface->stride + region.min.x, w);
|
rasterGrayscale8(surface->buf8, 255, (y + region.min.y) * surface->stride + region.min.x, w);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -485,43 +499,41 @@ static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint8_t r, uin
|
||||||
/* Rle */
|
/* Rle */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRleData* rle, SwBlender maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRleData* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
{
|
{
|
||||||
auto span = rle->spans;
|
auto span = rle->spans;
|
||||||
auto cbuffer = surface->compositor->image.buf32;
|
auto cbuffer = surface->compositor->image.buf8;
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto color = surface->join(r, g, b, a);
|
uint8_t src;
|
||||||
uint32_t src;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
||||||
auto cmp = &cbuffer[span->y * cstride + span->x];
|
auto cmp = &cbuffer[span->y * cstride + span->x];
|
||||||
if (span->coverage == 255) src = color;
|
if (span->coverage == 255) src = a;
|
||||||
else src = ALPHA_BLEND(color, span->coverage);
|
else src = MULTIPLY(a, span->coverage);
|
||||||
auto ialpha = IA(src);
|
auto ialpha = 255 - src;
|
||||||
for (auto x = 0; x < span->len; ++x, ++cmp) {
|
for (auto x = 0; x < span->len; ++x, ++cmp) {
|
||||||
*cmp = maskOp(src, *cmp, ialpha);
|
*cmp = maskOp(src, *cmp, ialpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _rasterDirectMaskedRle(SwSurface* surface, SwRleData* rle, SwBlender maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
static bool _rasterDirectMaskedRle(SwSurface* surface, SwRleData* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
{
|
{
|
||||||
auto span = rle->spans;
|
auto span = rle->spans;
|
||||||
auto cbuffer = surface->compositor->image.buf32;
|
auto cbuffer = surface->compositor->image.buf8;
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto color = surface->join(r, g, b, a);
|
uint8_t src;
|
||||||
uint32_t src;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
|
||||||
auto cmp = &cbuffer[span->y * cstride + span->x];
|
auto cmp = &cbuffer[span->y * cstride + span->x];
|
||||||
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
auto dst = &surface->buf8[span->y * surface->stride + span->x];
|
||||||
if (span->coverage == 255) src = color;
|
if (span->coverage == 255) src = a;
|
||||||
else src = ALPHA_BLEND(color, span->coverage);
|
else src = MULTIPLY(a, span->coverage);
|
||||||
for (auto x = 0; x < span->len; ++x, ++cmp, ++dst) {
|
for (auto x = 0; x < span->len; ++x, ++cmp, ++dst) {
|
||||||
auto tmp = maskOp(src, *cmp, 0); //not use alpha
|
auto tmp = maskOp(src, *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -532,11 +544,10 @@ static bool _rasterMaskedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint
|
||||||
{
|
{
|
||||||
TVGLOG("SW_ENGINE", "Masked(%d) Rle", (int)surface->compositor->method);
|
TVGLOG("SW_ENGINE", "Masked(%d) Rle", (int)surface->compositor->method);
|
||||||
|
|
||||||
//32bit channels composition
|
//8bit masking channels composition
|
||||||
if (surface->channelSize != sizeof(uint32_t)) return false;
|
if (surface->channelSize != sizeof(uint8_t)) return false;
|
||||||
|
|
||||||
auto maskOp = _getMaskOp(surface->compositor->method);
|
auto maskOp = _getMaskOp(surface->compositor->method);
|
||||||
|
|
||||||
if (_direct(surface->compositor->method)) return _rasterDirectMaskedRle(surface, rle, maskOp, r, g, b, a);
|
if (_direct(surface->compositor->method)) return _rasterDirectMaskedRle(surface, rle, maskOp, r, g, b, a);
|
||||||
else return _rasterCompositeMaskedRle(surface, rle, maskOp, r, g, b, a);
|
else return _rasterCompositeMaskedRle(surface, rle, maskOp, r, g, b, a);
|
||||||
return false;
|
return false;
|
||||||
|
@ -673,7 +684,8 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g,
|
||||||
/* RLE Scaled Image */
|
/* RLE Scaled Image */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static bool _rasterCompositeScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwBlender maskOp, SwBlender amaskOp, uint8_t opacity)
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
|
static bool _rasterCompositeScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
||||||
auto sampleSize = _sampleSize(image->scale);
|
auto sampleSize = _sampleSize(image->scale);
|
||||||
|
@ -683,21 +695,22 @@ static bool _rasterCompositeScaledMaskedRleImage(SwSurface* surface, const SwIma
|
||||||
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
||||||
auto sy = span->y * itransform->e22 + itransform->e23;
|
auto sy = span->y * itransform->e22 + itransform->e23;
|
||||||
if ((uint32_t)sy >= image->h) continue;
|
if ((uint32_t)sy >= image->h) continue;
|
||||||
auto cmp = &surface->compositor->image.buf32[span->y * surface->compositor->image.stride + span->x];
|
auto cmp = &surface->compositor->image.buf8[span->y * surface->compositor->image.stride + span->x];
|
||||||
auto a = MULTIPLY(span->coverage, opacity);
|
auto a = MULTIPLY(span->coverage, opacity);
|
||||||
if (a == 255) {
|
if (a == 255) {
|
||||||
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
|
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
|
||||||
auto sx = x * itransform->e11 + itransform->e13;
|
auto sx = x * itransform->e11 + itransform->e13;
|
||||||
if ((uint32_t)sx >= image->w) continue;
|
if ((uint32_t)sx >= image->w) continue;
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
||||||
*cmp = maskOp(src, *cmp, 255);
|
*cmp = maskOp(src, *cmp, ~src);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
|
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp) {
|
||||||
auto sx = x * itransform->e11 + itransform->e13;
|
auto sx = x * itransform->e11 + itransform->e13;
|
||||||
if ((uint32_t)sx >= image->w) continue;
|
if ((uint32_t)sx >= image->w) continue;
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
||||||
*cmp = amaskOp(src, *cmp, a);
|
auto tmp = MULTIPLY(src, a);
|
||||||
|
*cmp = maskOp(tmp, *cmp, ~tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -705,7 +718,7 @@ static bool _rasterCompositeScaledMaskedRleImage(SwSurface* surface, const SwIma
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _rasterDirectScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwBlender maskOp, SwBlender amaskOp, uint8_t opacity)
|
static bool _rasterDirectScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
||||||
auto sampleSize = _sampleSize(image->scale);
|
auto sampleSize = _sampleSize(image->scale);
|
||||||
|
@ -715,40 +728,43 @@ static bool _rasterDirectScaledMaskedRleImage(SwSurface* surface, const SwImage*
|
||||||
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
||||||
auto sy = span->y * itransform->e22 + itransform->e23;
|
auto sy = span->y * itransform->e22 + itransform->e23;
|
||||||
if ((uint32_t)sy >= image->h) continue;
|
if ((uint32_t)sy >= image->h) continue;
|
||||||
auto cmp = &surface->compositor->image.buf32[span->y * surface->compositor->image.stride + span->x];
|
auto cmp = &surface->compositor->image.buf8[span->y * surface->compositor->image.stride + span->x];
|
||||||
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
auto dst = &surface->buf8[span->y * surface->stride + span->x];
|
||||||
auto a = MULTIPLY(span->coverage, opacity);
|
auto a = MULTIPLY(span->coverage, opacity);
|
||||||
if (a == 255) {
|
if (a == 255) {
|
||||||
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp, ++dst) {
|
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp, ++dst) {
|
||||||
auto sx = x * itransform->e11 + itransform->e13;
|
auto sx = x * itransform->e11 + itransform->e13;
|
||||||
if ((uint32_t)sx >= image->w) continue;
|
if ((uint32_t)sx >= image->w) continue;
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
||||||
auto tmp = maskOp(src, *cmp, 0); //not use alpha
|
auto tmp = maskOp(src, *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp, ++dst) {
|
for (uint32_t x = static_cast<uint32_t>(span->x); x < static_cast<uint32_t>(span->x) + span->len; ++x, ++cmp, ++dst) {
|
||||||
auto sx = x * itransform->e11 + itransform->e13;
|
auto sx = x * itransform->e11 + itransform->e13;
|
||||||
if ((uint32_t)sx >= image->w) continue;
|
if ((uint32_t)sx >= image->w) continue;
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
||||||
auto tmp = amaskOp(src, *cmp, a);
|
auto tmp = maskOp(MULTIPLY(src, a), *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool _rasterScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
static bool _rasterScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
||||||
{
|
{
|
||||||
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
TVGLOG("SW_ENGINE", "Scaled Masked(%d) Rle Image", (int)surface->compositor->method);
|
TVGLOG("SW_ENGINE", "Scaled Masked(%d) Rle Image", (int)surface->compositor->method);
|
||||||
|
|
||||||
auto maskOp = _getMaskOp(surface->compositor->method);
|
//8bit masking channels composition
|
||||||
auto amaskOp = _getAMaskOp(surface->compositor->method);
|
if (surface->channelSize != sizeof(uint8_t)) return false;
|
||||||
|
|
||||||
if (_direct(surface->compositor->method)) return _rasterDirectScaledMaskedRleImage(surface, image, itransform, region, maskOp, amaskOp, opacity);
|
auto maskOp = _getMaskOp(surface->compositor->method);
|
||||||
else return _rasterCompositeScaledMaskedRleImage(surface, image, itransform, region, maskOp, amaskOp, opacity);
|
if (_direct(surface->compositor->method)) return _rasterDirectScaledMaskedRleImage(surface, image, itransform, region, maskOp, opacity);
|
||||||
|
else return _rasterCompositeScaledMaskedRleImage(surface, image, itransform, region, maskOp, opacity);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,66 +907,71 @@ static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matr
|
||||||
/* RLE Direct Image */
|
/* RLE Direct Image */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static bool _rasterCompositeDirectMaskedRleImage(SwSurface* surface, const SwImage* image, SwBlender maskOp, SwBlender amaskOp, uint8_t opacity)
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
|
static bool _rasterCompositeDirectMaskedRleImage(SwSurface* surface, const SwImage* image, SwMask maskOp, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto span = image->rle->spans;
|
auto span = image->rle->spans;
|
||||||
auto cbuffer = surface->compositor->image.buf32;
|
auto cbuffer = surface->compositor->image.buf8;
|
||||||
auto ctride = surface->compositor->image.stride;
|
auto ctride = surface->compositor->image.stride;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
||||||
auto src = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox);
|
auto src = image->buf8 + (span->y + image->oy) * image->stride + (span->x + image->ox);
|
||||||
auto cmp = &cbuffer[span->y * ctride + span->x];
|
auto cmp = &cbuffer[span->y * ctride + span->x];
|
||||||
auto alpha = MULTIPLY(span->coverage, opacity);
|
auto alpha = MULTIPLY(span->coverage, opacity);
|
||||||
if (alpha == 255) {
|
if (alpha == 255) {
|
||||||
for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) {
|
for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) {
|
||||||
*cmp = maskOp(*src, *cmp, IA(*src));
|
*cmp = maskOp(*src, *cmp, ~*src);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) {
|
for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) {
|
||||||
*cmp = amaskOp(*src, *cmp, alpha);
|
auto tmp = MULTIPLY(*src, alpha);
|
||||||
|
*cmp = maskOp(*src, *cmp, ~tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _rasterDirectDirectMaskedRleImage(SwSurface* surface, const SwImage* image, SwBlender maskOp, SwBlender amaskOp, uint8_t opacity)
|
static bool _rasterDirectDirectMaskedRleImage(SwSurface* surface, const SwImage* image, SwMask maskOp, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto span = image->rle->spans;
|
auto span = image->rle->spans;
|
||||||
auto cbuffer = surface->compositor->image.buf32;
|
auto cbuffer = surface->compositor->image.buf8;
|
||||||
auto ctride = surface->compositor->image.stride;
|
auto ctride = surface->compositor->image.stride;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
||||||
auto src = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox);
|
auto src = image->buf8 + (span->y + image->oy) * image->stride + (span->x + image->ox);
|
||||||
auto cmp = &cbuffer[span->y * ctride + span->x];
|
auto cmp = &cbuffer[span->y * ctride + span->x];
|
||||||
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
auto dst = &surface->buf8[span->y * surface->stride + span->x];
|
||||||
auto alpha = MULTIPLY(span->coverage, opacity);
|
auto alpha = MULTIPLY(span->coverage, opacity);
|
||||||
if (alpha == 255) {
|
if (alpha == 255) {
|
||||||
for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp, ++dst) {
|
for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp, ++dst) {
|
||||||
auto tmp = maskOp(*src, *cmp, 0); //not use alpha
|
auto tmp = maskOp(*src, *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = INTERPOLATE8(tmp, *dst, (255 - tmp));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp, ++dst) {
|
for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp, ++dst) {
|
||||||
auto tmp = amaskOp(*src, *cmp, alpha);
|
auto tmp = maskOp(MULTIPLY(*src, alpha), *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = INTERPOLATE8(tmp, *dst, (255 - tmp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool _rasterDirectMaskedRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity)
|
static bool _rasterDirectMaskedRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity)
|
||||||
{
|
{
|
||||||
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
TVGLOG("SW_ENGINE", "Direct Masked(%d) Rle Image", (int)surface->compositor->method);
|
TVGLOG("SW_ENGINE", "Direct Masked(%d) Rle Image", (int)surface->compositor->method);
|
||||||
|
|
||||||
auto maskOp = _getMaskOp(surface->compositor->method);
|
//8bit masking channels composition
|
||||||
auto amaskOp = _getAMaskOp(surface->compositor->method);
|
if (surface->channelSize != sizeof(uint8_t)) return false;
|
||||||
|
|
||||||
if (_direct(surface->compositor->method)) _rasterDirectDirectMaskedRleImage(surface, image, maskOp, amaskOp, opacity);
|
auto maskOp = _getMaskOp(surface->compositor->method);
|
||||||
else return _rasterCompositeDirectMaskedRleImage(surface, image, maskOp, amaskOp, opacity);
|
if (_direct(surface->compositor->method)) _rasterDirectDirectMaskedRleImage(surface, image, maskOp, opacity);
|
||||||
|
else return _rasterCompositeDirectMaskedRleImage(surface, image, maskOp, opacity);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1055,13 +1076,14 @@ static bool _directRleImage(SwSurface* surface, const SwImage* image, uint8_t op
|
||||||
/*Scaled Image */
|
/*Scaled Image */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static bool _rasterCompositeScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwBlender maskOp, SwBlender amaskOp, uint8_t opacity)
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
|
static bool _rasterCompositeScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
||||||
auto sampleSize = _sampleSize(image->scale);
|
auto sampleSize = _sampleSize(image->scale);
|
||||||
auto sampleSize2 = sampleSize * sampleSize;
|
auto sampleSize2 = sampleSize * sampleSize;
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x);
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x);
|
||||||
|
|
||||||
for (auto y = region.min.y; y < region.max.y; ++y) {
|
for (auto y = region.min.y; y < region.max.y; ++y) {
|
||||||
auto sy = y * itransform->e22 + itransform->e23;
|
auto sy = y * itransform->e22 + itransform->e23;
|
||||||
|
@ -1071,31 +1093,32 @@ static bool _rasterCompositeScaledMaskedImage(SwSurface* surface, const SwImage*
|
||||||
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
|
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
|
||||||
auto sx = x * itransform->e11 + itransform->e13;
|
auto sx = x * itransform->e11 + itransform->e13;
|
||||||
if ((uint32_t)sx >= image->w) continue;
|
if ((uint32_t)sx >= image->w) continue;
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
||||||
*cmp = maskOp(src, *cmp, IA(src));
|
*cmp = maskOp(src, *cmp, ~src);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
|
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) {
|
||||||
auto sx = x * itransform->e11 + itransform->e13;
|
auto sx = x * itransform->e11 + itransform->e13;
|
||||||
if ((uint32_t)sx >= image->w) continue;
|
if ((uint32_t)sx >= image->w) continue;
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
||||||
*cmp = amaskOp(src, *cmp, opacity);
|
auto tmp = MULTIPLY(src, opacity);
|
||||||
|
*cmp = maskOp(tmp, *cmp, ~tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cbuffer += cstride;
|
cbuffer += cstride;
|
||||||
}
|
}
|
||||||
return _rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _rasterDirectScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwBlender maskOp, SwBlender amaskOp, uint8_t opacity)
|
static bool _rasterDirectScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
||||||
auto sampleSize = _sampleSize(image->scale);
|
auto sampleSize = _sampleSize(image->scale);
|
||||||
auto sampleSize2 = sampleSize * sampleSize;
|
auto sampleSize2 = sampleSize * sampleSize;
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x);
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x);
|
||||||
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x);
|
||||||
|
|
||||||
for (auto y = region.min.y; y < region.max.y; ++y) {
|
for (auto y = region.min.y; y < region.max.y; ++y) {
|
||||||
auto sy = y * itransform->e22 + itransform->e23;
|
auto sy = y * itransform->e22 + itransform->e23;
|
||||||
|
@ -1106,17 +1129,18 @@ static bool _rasterDirectScaledMaskedImage(SwSurface* surface, const SwImage* im
|
||||||
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) {
|
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) {
|
||||||
auto sx = x * itransform->e11 + itransform->e13;
|
auto sx = x * itransform->e11 + itransform->e13;
|
||||||
if ((uint32_t)sx >= image->w) continue;
|
if ((uint32_t)sx >= image->w) continue;
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
||||||
auto tmp = maskOp(src, *cmp, 0); //not use alpha
|
auto tmp = maskOp(src, *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) {
|
for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) {
|
||||||
auto sx = x * itransform->e11 + itransform->e13;
|
auto sx = x * itransform->e11 + itransform->e13;
|
||||||
if ((uint32_t)sx >= image->w) continue;
|
if ((uint32_t)sx >= image->w) continue;
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, sampleSize, sampleSize2);
|
||||||
auto tmp = amaskOp(src, *cmp, opacity);
|
auto tmp = MULTIPLY(src, opacity);
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
auto tmp2 = maskOp(tmp, *cmp, 0); //not use alpha
|
||||||
|
*dst = tmp2 + MULTIPLY(*dst, ~tmp2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cbuffer += cstride;
|
cbuffer += cstride;
|
||||||
|
@ -1124,17 +1148,17 @@ static bool _rasterDirectScaledMaskedImage(SwSurface* surface, const SwImage* im
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
||||||
{
|
{
|
||||||
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
TVGLOG("SW_ENGINE", "Scaled Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
TVGLOG("SW_ENGINE", "Scaled Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
||||||
|
|
||||||
auto maskOp = _getMaskOp(surface->compositor->method);
|
auto maskOp = _getMaskOp(surface->compositor->method);
|
||||||
auto amaskOp = _getAMaskOp(surface->compositor->method);
|
if (_direct(surface->compositor->method)) return _rasterDirectScaledMaskedImage(surface, image, itransform, region, maskOp, opacity);
|
||||||
|
else return _rasterCompositeScaledMaskedImage(surface, image, itransform, region, maskOp, opacity);
|
||||||
if (_direct(surface->compositor->method)) return _rasterDirectScaledMaskedImage(surface, image, itransform, region, maskOp, amaskOp, opacity);
|
#endif
|
||||||
else return _rasterCompositeScaledMaskedImage(surface, image, itransform, region, maskOp, amaskOp, opacity);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1269,43 +1293,45 @@ static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix*
|
||||||
/* Direct Image */
|
/* Direct Image */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static bool _rasterCompositeDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, SwBlender maskOp, SwBlender amaskOp, uint8_t opacity)
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
|
static bool _rasterCompositeDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, SwMask maskOp, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
||||||
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
|
|
||||||
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x); //compositor buffer
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); //compositor buffer
|
||||||
auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
|
auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
|
||||||
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
auto cmp = cbuffer;
|
auto cmp = cbuffer;
|
||||||
auto src = sbuffer;
|
auto src = sbuffer;
|
||||||
if (opacity == 255) {
|
if (opacity == 255) {
|
||||||
for (uint32_t x = 0; x < w; ++x, ++src, ++cmp) {
|
for (uint32_t x = 0; x < w; ++x, ++src, ++cmp) {
|
||||||
*cmp = maskOp(*src, *cmp, IA(*src));
|
*cmp = maskOp(*src, *cmp, ~*src);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t x = 0; x < w; ++x, ++src, ++cmp) {
|
for (uint32_t x = 0; x < w; ++x, ++src, ++cmp) {
|
||||||
*cmp = amaskOp(*src, *cmp, opacity);
|
auto tmp = MULTIPLY(*src, opacity);
|
||||||
|
*cmp = maskOp(tmp, *cmp, ~tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cbuffer += cstride;
|
cbuffer += cstride;
|
||||||
sbuffer += image->stride;
|
sbuffer += image->stride;
|
||||||
}
|
}
|
||||||
return _rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _rasterDirectDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, SwBlender maskOp, SwBlender amaskOp, uint8_t opacity)
|
static bool _rasterDirectDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, SwMask maskOp, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
||||||
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
|
|
||||||
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x); //compositor buffer
|
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x); //compositor buffer
|
||||||
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); //destination buffer
|
auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); //destination buffer
|
||||||
auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
|
auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
|
||||||
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
auto cmp = cbuffer;
|
auto cmp = cbuffer;
|
||||||
|
@ -1314,12 +1340,12 @@ static bool _rasterDirectDirectMaskedImage(SwSurface* surface, const SwImage* im
|
||||||
if (opacity == 255) {
|
if (opacity == 255) {
|
||||||
for (uint32_t x = 0; x < w; ++x, ++src, ++cmp, ++dst) {
|
for (uint32_t x = 0; x < w; ++x, ++src, ++cmp, ++dst) {
|
||||||
auto tmp = maskOp(*src, *cmp, 0); //not use alpha
|
auto tmp = maskOp(*src, *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t x = 0; x < w; ++x, ++src, ++cmp, ++dst) {
|
for (uint32_t x = 0; x < w; ++x, ++src, ++cmp, ++dst) {
|
||||||
auto tmp = amaskOp(*src, *cmp, opacity);
|
auto tmp = maskOp(MULTIPLY(*src, opacity), *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cbuffer += cstride;
|
cbuffer += cstride;
|
||||||
|
@ -1328,17 +1354,17 @@ static bool _rasterDirectDirectMaskedImage(SwSurface* surface, const SwImage* im
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool _rasterDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
|
static bool _rasterDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
|
||||||
{
|
{
|
||||||
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
TVGLOG("SW_ENGINE", "Direct Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
TVGLOG("SW_ENGINE", "Direct Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
||||||
|
|
||||||
auto maskOp = _getMaskOp(surface->compositor->method);
|
auto maskOp = _getMaskOp(surface->compositor->method);
|
||||||
auto amaskOp = _getAMaskOp(surface->compositor->method);
|
if (_direct(surface->compositor->method)) return _rasterDirectDirectMaskedImage(surface, image, region, maskOp, opacity);
|
||||||
|
else return _rasterCompositeDirectMaskedImage(surface, image, region, maskOp, opacity);
|
||||||
if (_direct(surface->compositor->method)) return _rasterDirectDirectMaskedImage(surface, image, region, maskOp, amaskOp, opacity);
|
#endif
|
||||||
else return _rasterCompositeDirectMaskedImage(surface, image, region, maskOp, amaskOp, opacity);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1466,20 +1492,20 @@ static bool _rasterImage(SwSurface* surface, SwImage* image, const Matrix* trans
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Rect Gradient */
|
/* Rect Gradient */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
#if 0
|
||||||
template<typename fillMethod>
|
template<typename fillMethod>
|
||||||
static bool _rasterCompositeGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwBlender maskOp)
|
static bool _rasterCompositeGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwBlender maskOp)
|
||||||
{
|
{
|
||||||
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
|
||||||
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x);
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x);
|
||||||
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, w, maskOp, 255);
|
fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, w, maskOp, 255);
|
||||||
cbuffer += surface->stride;
|
cbuffer += surface->stride;
|
||||||
}
|
}
|
||||||
return _rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox, 255);
|
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1499,19 +1525,21 @@ static bool _rasterDirectGradientMaskedRect(SwSurface* surface, const SwBBox& re
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename fillMethod>
|
template<typename fillMethod>
|
||||||
static bool _rasterGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
|
static bool _rasterGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
auto method = surface->compositor->method;
|
auto method = surface->compositor->method;
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Masked(%d) Gradient [Region: %lu %lu %lu %lu]", (int)method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
TVGLOG("SW_ENGINE", "Masked(%d) Gradient [Region: %lu %lu %lu %lu]", (int)method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
||||||
|
|
||||||
auto amaskOp = _getAMaskOp(method);
|
auto maskOp = _getMaskOp(method);
|
||||||
|
|
||||||
if (_direct(method)) return _rasterDirectGradientMaskedRect<fillMethod>(surface, region, fill, amaskOp);
|
if (_direct(method)) return _rasterDirectGradientMaskedRect<fillMethod>(surface, region, fill, maskOp);
|
||||||
else return _rasterCompositeGradientMaskedRect<fillMethod>(surface, region, fill, amaskOp);
|
else return _rasterCompositeGradientMaskedRect<fillMethod>(surface, region, fill, maskOp);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1623,7 +1651,7 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region,
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Rle Gradient */
|
/* Rle Gradient */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
#if 0
|
||||||
template<typename fillMethod>
|
template<typename fillMethod>
|
||||||
static bool _rasterCompositeGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwBlender maskOp)
|
static bool _rasterCompositeGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwBlender maskOp)
|
||||||
{
|
{
|
||||||
|
@ -1654,7 +1682,7 @@ static bool _rasterDirectGradientMaskedRle(SwSurface* surface, const SwRleData*
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename fillMethod>
|
template<typename fillMethod>
|
||||||
static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
|
static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill)
|
||||||
|
@ -1665,8 +1693,8 @@ static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRleData* rle, c
|
||||||
|
|
||||||
auto amaskOp = _getAMaskOp(method);
|
auto amaskOp = _getAMaskOp(method);
|
||||||
|
|
||||||
if (_direct(method)) return _rasterDirectGradientMaskedRle<fillMethod>(surface, rle, fill, amaskOp);
|
//if (_direct(method)) return _rasterDirectGradientMaskedRle<fillMethod>(surface, rle, fill, amaskOp);
|
||||||
else return _rasterCompositeGradientMaskedRle<fillMethod>(surface, rle, fill, amaskOp);
|
//else return _rasterCompositeGradientMaskedRle<fillMethod>(surface, rle, fill, amaskOp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,13 +72,15 @@ static bool _arrange(const SwImage* image, const SwBBox* region, int& yStart, in
|
||||||
|
|
||||||
static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity, uint8_t dirFlag = 0)
|
static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity, uint8_t dirFlag = 0)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
auto maskOp = _getMaskOp(surface->compositor->method);
|
auto maskOp = _getMaskOp(surface->compositor->method);
|
||||||
auto amaskOp = _getAMaskOp(surface->compositor->method);
|
|
||||||
auto direct = _direct(surface->compositor->method);
|
auto direct = _direct(surface->compositor->method);
|
||||||
float _dudx = dudx, _dvdx = dvdx;
|
float _dudx = dudx, _dvdx = dvdx;
|
||||||
float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya;
|
float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya;
|
||||||
float _xa = xa, _xb = xb, _ua = ua, _va = va;
|
float _xa = xa, _xb = xb, _ua = ua, _va = va;
|
||||||
auto sbuf = image->buf32;
|
auto sbuf = image->buf8;
|
||||||
int32_t sw = static_cast<int32_t>(image->stride);
|
int32_t sw = static_cast<int32_t>(image->stride);
|
||||||
int32_t sh = image->h;
|
int32_t sh = image->h;
|
||||||
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
|
int32_t x1, x2, x, y, ar, ab, iru, irv, px, ay;
|
||||||
|
@ -138,8 +140,8 @@ static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage*
|
||||||
|
|
||||||
x = x1;
|
x = x1;
|
||||||
|
|
||||||
auto cmp = &surface->compositor->image.buf32[y * surface->compositor->image.stride + x1];
|
auto cmp = &surface->compositor->image.buf8[y * surface->compositor->image.stride + x1];
|
||||||
auto dst = &surface->buf32[y * surface->stride + x1];
|
auto dst = &surface->buf8[y * surface->stride + x1];
|
||||||
|
|
||||||
if (opacity == 255) {
|
if (opacity == 255) {
|
||||||
//Draw horizontal line
|
//Draw horizontal line
|
||||||
|
@ -177,10 +179,10 @@ static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage*
|
||||||
}
|
}
|
||||||
if (direct) {
|
if (direct) {
|
||||||
auto tmp = maskOp(px, *cmp, 0); //not use alpha
|
auto tmp = maskOp(px, *cmp, 0); //not use alpha
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
++dst;
|
++dst;
|
||||||
} else {
|
} else {
|
||||||
*cmp = maskOp(px, *cmp, IA(px));
|
*cmp = maskOp(px, *cmp, ~px);
|
||||||
}
|
}
|
||||||
++cmp;
|
++cmp;
|
||||||
|
|
||||||
|
@ -226,11 +228,12 @@ static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage*
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direct) {
|
if (direct) {
|
||||||
auto tmp = amaskOp(px, *cmp, opacity);
|
auto tmp = maskOp(MULTIPLY(px, opacity), *cmp, 0);
|
||||||
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
|
*dst = tmp + MULTIPLY(*dst, ~tmp);
|
||||||
++dst;
|
++dst;
|
||||||
} else {
|
} else {
|
||||||
*cmp = amaskOp(px, *cmp, opacity);
|
auto tmp = MULTIPLY(px, opacity);
|
||||||
|
*cmp = maskOp(tmp, *cmp, ~px);
|
||||||
}
|
}
|
||||||
++cmp;
|
++cmp;
|
||||||
|
|
||||||
|
@ -259,6 +262,7 @@ static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage*
|
||||||
va = _va;
|
va = _va;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1124,9 +1128,11 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const
|
||||||
|
|
||||||
_rasterPolygonImage(surface, image, region, polygon, aaSpans, opacity);
|
_rasterPolygonImage(surface, image, region, polygon, aaSpans, opacity);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (_compositing(surface) && _masking(surface) && !_direct(surface->compositor->method)) {
|
if (_compositing(surface) && _masking(surface) && !_direct(surface->compositor->method)) {
|
||||||
_rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
_compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return _apply(surface, aaSpans);
|
return _apply(surface, aaSpans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1179,9 +1185,11 @@ static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, c
|
||||||
for (uint32_t i = 0; i < mesh->triangleCnt; i++) {
|
for (uint32_t i = 0; i < mesh->triangleCnt; i++) {
|
||||||
_rasterPolygonImage(surface, image, region, transformedTris[i], aaSpans, opacity);
|
_rasterPolygonImage(surface, image, region, transformedTris[i], aaSpans, opacity);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
if (_compositing(surface) && _masking(surface) && !_direct(surface->compositor->method)) {
|
if (_compositing(surface) && _masking(surface) && !_direct(surface->compositor->method)) {
|
||||||
_rasterDirectImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
_compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
_apply(surface, aaSpans);
|
_apply(surface, aaSpans);
|
||||||
}
|
}
|
||||||
free(transformedTris);
|
free(transformedTris);
|
||||||
|
|
|
@ -297,13 +297,14 @@ static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, Composi
|
||||||
switch(method) {
|
switch(method) {
|
||||||
case CompositeMethod::AlphaMask:
|
case CompositeMethod::AlphaMask:
|
||||||
case CompositeMethod::InvAlphaMask:
|
case CompositeMethod::InvAlphaMask:
|
||||||
return ColorSpace::Grayscale8;
|
|
||||||
case CompositeMethod::LumaMask:
|
|
||||||
case CompositeMethod::InvLumaMask:
|
|
||||||
case CompositeMethod::AddMask:
|
case CompositeMethod::AddMask:
|
||||||
|
case CompositeMethod::DifferenceMask:
|
||||||
case CompositeMethod::SubtractMask:
|
case CompositeMethod::SubtractMask:
|
||||||
case CompositeMethod::IntersectMask:
|
case CompositeMethod::IntersectMask:
|
||||||
case CompositeMethod::DifferenceMask:
|
return ColorSpace::Grayscale8;
|
||||||
|
//TODO: Optimize Luma/InvLuma colorspace to Grayscale8
|
||||||
|
case CompositeMethod::LumaMask:
|
||||||
|
case CompositeMethod::InvLumaMask:
|
||||||
return renderer.colorSpace();
|
return renderer.colorSpace();
|
||||||
default:
|
default:
|
||||||
TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method);
|
TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method);
|
||||||
|
|
Loading…
Add table
Reference in a new issue