common paint: fix the wrong fast track logic.

There was a missing sorting between the left-top & right-bottom corner.
that results in the negative values of the viewport...

Now fixed it.

+ refactored to use math functions...
+ still it's a buggy, sometimes no draw at 90' in stress. don't know reason. :(
This commit is contained in:
Hermet Park 2021-11-22 12:31:23 +09:00 committed by Hermet Park
parent baab43aff2
commit f887edf562
5 changed files with 43 additions and 34 deletions

View file

@ -235,7 +235,7 @@ RenderData GlRenderer::prepare(const Shape& shape, RenderData data, const Render
RenderRegion GlRenderer::viewport() RenderRegion GlRenderer::viewport()
{ {
return {0, 0, UINT32_MAX, UINT32_MAX}; return {0, 0, INT32_MAX, INT32_MAX};
} }

View file

@ -287,8 +287,7 @@ RenderRegion SwRenderer::viewport()
bool SwRenderer::viewport(const RenderRegion& vp) bool SwRenderer::viewport(const RenderRegion& vp)
{ {
this->vport = vp; vport = vp;
return true; return true;
} }
@ -456,9 +455,11 @@ Compositor* SwRenderer::target(const RenderRegion& region)
auto y = region.y; auto y = region.y;
auto w = region.w; auto w = region.w;
auto h = region.h; auto h = region.h;
auto sw = static_cast<int32_t>(surface->w);
auto sh = static_cast<int32_t>(surface->h);
//Out of boundary //Out of boundary
if (x > surface->w || y > surface->h) return nullptr; if (x > sw || y > sh) return nullptr;
SwSurface* cmp = nullptr; SwSurface* cmp = nullptr;
@ -488,8 +489,8 @@ Compositor* SwRenderer::target(const RenderRegion& region)
} }
//Boundary Check //Boundary Check
if (x + w > surface->w) w = (surface->w - x); if (x + w > sw) w = (sw - x);
if (y + h > surface->h) h = (surface->h - y); if (y + h > sh) h = (sh - y);
TVGLOG("SW_ENGINE", "Using intermediate composition [Region: %d %d %d %d]", x, y, w, h); TVGLOG("SW_ENGINE", "Using intermediate composition [Region: %d %d %d %d]", x, y, w, h);

View file

@ -19,8 +19,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
#include <float.h>
#include <math.h>
#include "tvgMath.h" #include "tvgMath.h"
#include "tvgPaint.h" #include "tvgPaint.h"
@ -40,7 +38,7 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform,
if (rTransform) rTransform->update(); if (rTransform) rTransform->update();
//No Rotation? //No rotational.
if (pTransform && !mathRightAngle(&pTransform->m)) return false; if (pTransform && !mathRightAngle(&pTransform->m)) return false;
if (rTransform && !mathRightAngle(&rTransform->m)) return false; if (rTransform && !mathRightAngle(&rTransform->m)) return false;
@ -53,32 +51,39 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform,
if ((mathEqual(pt1->x, pt2->x) && mathEqual(pt2->y, pt3->y) && mathEqual(pt3->x, pt4->x) && mathEqual(pt1->y, pt4->y)) || if ((mathEqual(pt1->x, pt2->x) && mathEqual(pt2->y, pt3->y) && mathEqual(pt3->x, pt4->x) && mathEqual(pt1->y, pt4->y)) ||
(mathEqual(pt2->x, pt3->x) && mathEqual(pt1->y, pt2->y) && mathEqual(pt1->x, pt4->x) && mathEqual(pt3->y, pt4->y))) { (mathEqual(pt2->x, pt3->x) && mathEqual(pt1->y, pt2->y) && mathEqual(pt1->x, pt4->x) && mathEqual(pt3->y, pt4->y))) {
auto x1 = pt1->x; auto v1 = *pt1;
auto y1 = pt1->y; auto v2 = *pt3;
auto x2 = pt3->x;
auto y2 = pt3->y;
if (rTransform) { if (rTransform) {
x1 = x1 * rTransform->m.e11 + rTransform->m.e13; mathMultiply(&v1, &rTransform->m);
y1 = y1 * rTransform->m.e22 + rTransform->m.e23; mathMultiply(&v2, &rTransform->m);
x2 = x2 * rTransform->m.e11 + rTransform->m.e13;
y2 = y2 * rTransform->m.e22 + rTransform->m.e23;
} }
if (pTransform) { if (pTransform) {
x1 = x1 * pTransform->m.e11 + pTransform->m.e13; mathMultiply(&v1, &pTransform->m);
y1 = y1 * pTransform->m.e22 + pTransform->m.e23; mathMultiply(&v2, &pTransform->m);
x2 = x2 * pTransform->m.e11 + pTransform->m.e13;
y2 = y2 * pTransform->m.e22 + pTransform->m.e23;
} }
if (x1 < 0.0f) x1 = 0.0f; //sorting
if (y1 < 0.0f) y1 = 0.0f; if (v1.x > v2.x) {
auto tmp = v2.x;
v2.x = v1.x;
v1.x = tmp;
}
viewport.x = static_cast<uint32_t>(x1); if (v1.y > v2.y) {
viewport.y = static_cast<uint32_t>(y1); auto tmp = v2.y;
viewport.w = static_cast<uint32_t>(x2 - x1 < 0 ? 0 : roundf(x2 - x1 + 0.5f)); v2.y = v1.y;
viewport.h = static_cast<uint32_t>(y2 - y1 < 0 ? 0 : roundf(y2 - y1 + 0.5f)); v1.y = tmp;
}
viewport.x = static_cast<int32_t>(v1.x);
viewport.y = static_cast<int32_t>(v1.y);
viewport.w = static_cast<int32_t>(v2.x - v1.x + 0.5f);
viewport.h = static_cast<int32_t>(v2.y - v1.y + 0.5f);
if (viewport.w < 0) viewport.w = 0;
if (viewport.h < 0) viewport.h = 0;
return true; return true;
} }
@ -197,6 +202,8 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
bool cmpFastTrack = false; bool cmpFastTrack = false;
if (cmpTarget) { if (cmpTarget) {
cmpTarget->pImpl->ctxFlag = ContextFlag::Invalid; //reset
/* If transform has no rotation factors && ClipPath / AlphaMasking is a simple rectangle, /* If transform has no rotation factors && ClipPath / AlphaMasking is a simple rectangle,
we can avoid regular ClipPath / AlphaMasking sequence but use viewport for performance */ we can avoid regular ClipPath / AlphaMasking sequence but use viewport for performance */
auto tryFastTrack = false; auto tryFastTrack = false;
@ -214,8 +221,6 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
viewport2.intersect(viewport); viewport2.intersect(viewport);
renderer.viewport(viewport2); renderer.viewport(viewport2);
cmpTarget->pImpl->ctxFlag |= ContextFlag::FastTrack; cmpTarget->pImpl->ctxFlag |= ContextFlag::FastTrack;
} else {
cmpTarget->pImpl->ctxFlag &= ~ContextFlag::FastTrack;
} }
} }
if (!cmpFastTrack) { if (!cmpFastTrack) {

View file

@ -49,7 +49,7 @@ struct Compositor
struct RenderRegion struct RenderRegion
{ {
uint32_t x, y, w, h; int32_t x, y, w, h;
void intersect(const RenderRegion& rhs) void intersect(const RenderRegion& rhs)
{ {
@ -62,6 +62,9 @@ struct RenderRegion
y = (y > rhs.y) ? y : rhs.y; y = (y > rhs.y) ? y : rhs.y;
w = ((x1 < x2) ? x1 : x2) - x; w = ((x1 < x2) ? x1 : x2) - x;
h = ((y1 < y2) ? y1 : y2) - y; h = ((y1 < y2) ? y1 : y2) - y;
if (w < 0) w = 0;
if (h < 0) h = 0;
} }
}; };

View file

@ -131,10 +131,10 @@ struct Scene::Impl
{ {
if (paints.count == 0) return {0, 0, 0, 0}; if (paints.count == 0) return {0, 0, 0, 0};
uint32_t x1 = UINT32_MAX; int32_t x1 = INT32_MAX;
uint32_t y1 = UINT32_MAX; int32_t y1 = INT32_MAX;
uint32_t x2 = 0; int32_t x2 = 0;
uint32_t y2 = 0; int32_t y2 = 0;
for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
auto region = (*paint)->pImpl->bounds(renderer); auto region = (*paint)->pImpl->bounds(renderer);