| Index: gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc
|
| diff --git a/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc b/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc
|
| index 65eca9ad36afcc8233508bcb22a70cae8970dcdb..6a588253da267154a4217ef13a664a25106541cd 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa_intel.cc
|
| @@ -712,7 +712,6 @@ const char ApplyFramebufferAttachmentCMAAINTELResourceManager::cmaa_frag_s1_[] =
|
| precision highp float;
|
| precision highp int;
|
|
|
| - \n#define SETTINGS_ALLOW_SHORT_Zs 1\n
|
| \n#define EDGE_DETECT_THRESHOLD 13.0f\n
|
| \n#define saturate(x) clamp((x), 0.0, 1.0)\n
|
|
|
| @@ -960,11 +959,7 @@ const char ApplyFramebufferAttachmentCMAAINTELResourceManager::cmaa_frag_s1_[] =
|
| }
|
| ///////////////////////////////////////////////////////////////////////
|
|
|
| - \n#ifdef SETTINGS_ALLOW_SHORT_Zs\n
|
| - int i = 1;
|
| - \n#else\n
|
| - int i = 2; // starting from 2 because we already know it's at least 2
|
| - \n#endif\n
|
| + int i = 2;
|
| for (; i < c_maxLineLength; i++) {
|
| uint edgeLeft = uint(
|
| texelFetch(g_src0TextureFlt,
|
| @@ -1533,74 +1528,187 @@ const char ApplyFramebufferAttachmentCMAAINTELResourceManager::cmaa_frag_s2_[] =
|
| // neighbouring pixel colours and apply them to the one currently
|
| // processed.
|
|
|
| - // 1.) L-like shape.
|
| - // For this shape, the total amount of screen colour will be
|
| - // preserved when this is a part of a (zigzag) diagonal line as the
|
| - // corners from the other side will do the same and take some of
|
| - // the current pixel's colour in return.
|
| - // However, in the case when this is an actual corner, the pixel's
|
| - // colour will be partially overwritten by it's 2 neighbours.
|
| - if( numberOfEdges == 2.0 )
|
| - {
|
| + // 1.) U-like shape (surrounded with edges from 3 sides)
|
| + if (numberOfEdges == 3.0) {
|
| + // with value of 0.13, the pixel will retain approx 72% of its
|
| + // colour and the remaining 28% will be picked from its 3
|
| + // neighbours (which are unlikely to be blurred too but could be)
|
| + blurCoeff = 0.13;
|
| + }
|
| +
|
| + // 2.) Completely surrounded with edges from all 4 sides
|
| + if (numberOfEdges == 4.0) {
|
| + // with value of 0.07, the pixel will retain 78% of its colour
|
| + // and the remaining 22% will come from its 4 neighbours (which
|
| + // are unlikely to be blurred)
|
| + blurCoeff = 0.07;
|
| + }
|
| +
|
| + // 3.) L-like shape.
|
| + // Two edge case is a bit complicated. We want to handle only staircase
|
| + // case. The staircase case consists of small staircase and Z shape.
|
| + // Define small staircase as at least 2 texels form Z shape.
|
| + // Standard form Variants
|
| + // __ |__ __ __ |__
|
| + // X| X| | X | X|
|
| + // ¯¯ ¯¯ ¯¯ ¯¯| ¯¯|
|
| + //
|
| + // Define Z shape as at least 4 texels form Z shape.
|
| + // __ __
|
| + // X|
|
| + // ¯¯ ¯¯
|
| + // Anything else will be skipped. e.g.
|
| + // Parallel |X|
|
| + //
|
| + // Isolated L shape
|
| + // _ _
|
| + // X| X| |X |X
|
| + // ¯¯ ¯¯
|
| + // Large L shape
|
| + // _ _ | | _ _
|
| + // X| X| |X |X
|
| + // | ¯¯¯¯ ¯¯¯¯ |
|
| + //
|
| + // etc..
|
| + if (numberOfEdges == 2.0) {
|
| // with value of 0.15, the pixel will retain approx 77% of its
|
| // colour and the remaining 23% will come from its 2 neighbours
|
| // (which are likely to be blurred too in the opposite direction)
|
| blurCoeff = 0.15;
|
|
|
| - // Only do blending if it's L shape - if we're between two
|
| - // parallel edges, don't do anything
|
| - blurCoeff *= (1.0 - fromBelow * fromAbove) *
|
| - (1.0 - fromRight * fromLeft);
|
| -
|
| - if (blurCoeff == 0.0)
|
| - continue;
|
| -
|
| uint packedEdgesL = packedEdgesArray[(0 + _x) * 4 + (1 + _y)];
|
| uint packedEdgesB = packedEdgesArray[(1 + _x) * 4 + (0 + _y)];
|
| uint packedEdgesR = packedEdgesArray[(2 + _x) * 4 + (1 + _y)];
|
| uint packedEdgesT = packedEdgesArray[(1 + _x) * 4 + (2 + _y)];
|
|
|
| - // Don't blend large L shape because it would be the intended shape
|
| - // with high probability. e.g. rectangle
|
| - // large_l1 large_l2 large_l3 large_l4
|
| - // _ _ | | _ _
|
| - // X| X| |X |X
|
| - // | ¯¯¯¯ ¯¯¯¯ |
|
| - bool large_l1 = (packedEdgesC == (0x01u | 0x02u)) &&
|
| - bool(packedEdgesL & 0x02u) &&
|
| - bool(packedEdgesB & 0x01u);
|
| - bool large_l2 = (packedEdgesC == (0x01u | 0x08u)) &&
|
| - bool(packedEdgesL & 0x08u) &&
|
| - bool(packedEdgesT & 0x01u);
|
| - bool large_l3 = (packedEdgesC == (0x04u | 0x08u)) &&
|
| - bool(packedEdgesR & 0x08u) &&
|
| - bool(packedEdgesT & 0x04u);
|
| - bool large_l4 = (packedEdgesC == (0x02u | 0x04u)) &&
|
| - bool(packedEdgesR & 0x02u) &&
|
| - bool(packedEdgesB & 0x04u);
|
| - if (large_l1 || large_l2 || large_l3 || large_l4)
|
| + // HorizontalA HorizontalB HorizontalC HorizontalD
|
| + // _ _ _ _
|
| + // X| X| |X |X
|
| + // ¯¯ ¯¯ ¯¯ ¯¯
|
| + bool isHorizontalA = ((packedEdgesC) == (0x01u | 0x02u)) &&
|
| + ((packedEdgesR & 0x08u) == 0x08u);
|
| + bool isHorizontalB = ((packedEdgesC) == (0x01u | 0x08u)) &&
|
| + ((packedEdgesR & 0x02u) == 0x02u);
|
| + bool isHorizontalC = ((packedEdgesC) == (0x04u | 0x08u)) &&
|
| + ((packedEdgesL & 0x02u) == 0x02u);
|
| + bool isHorizontalD = ((packedEdgesC) == (0x02u | 0x04u)) &&
|
| + ((packedEdgesL & 0x08u) == 0x08u);
|
| +
|
| + // VerticalA VerticalB VerticalC VerticalD
|
| + // _| |_ X| |X
|
| + // |X X| |¯¯ ¯¯|
|
| + bool isVerticalA = ((packedEdgesC) == (0x02u | 0x04u)) &&
|
| + ((packedEdgesT & 0x01u) == 0x01u);
|
| + bool isVerticalB = ((packedEdgesC) == (0x01u | 0x02u)) &&
|
| + ((packedEdgesT & 0x04u) == 0x04u);
|
| + bool isVerticalC = ((packedEdgesC) == (0x01u | 0x08u)) &&
|
| + ((packedEdgesB & 0x04u) == 0x04u);
|
| + bool isVerticalD = ((packedEdgesC) == (0x04u | 0x08u)) &&
|
| + ((packedEdgesT & 0x01u) == 0x01u);
|
| +
|
| + bool isStaircase = isHorizontalA || isHorizontalB || isHorizontalC ||
|
| + isHorizontalD || isVerticalA || isVerticalB ||
|
| + isVerticalC || isVerticalD;
|
| +
|
| + // Skip anything else as mentioned above.
|
| + if (!isStaircase)
|
| continue;
|
| - }
|
|
|
| - // 2.) U-like shape (surrounded with edges from 3 sides)
|
| - if (numberOfEdges == 3.0) {
|
| - // with value of 0.13, the pixel will retain approx 72% of its
|
| - // colour and the remaining 28% will be picked from its 3
|
| - // neighbours (which are unlikely to be blurred too but could be)
|
| - blurCoeff = 0.13;
|
| - }
|
| + bool isHCandidate = isHorizontalA || isHorizontalB;
|
| + bool isVCandidate = isVerticalA || isVerticalB;
|
| + bool isZCandidate = isHCandidate || isVCandidate;
|
| +
|
| + // isHorizontalA/B are the same to isHorizontalC/D in another fragment
|
| + if (isZCandidate) {
|
| + bool horizontal = isHCandidate;
|
| +
|
| + // what if both are candidates? do additional pruning (still not
|
| + // 100% but gets rid of worst case errors)
|
| + if (isHCandidate && isVCandidate)
|
| + horizontal =
|
| + (isHorizontalA && ((packedEdgesL & 0x02u) == 0x02u)) ||
|
| + (isHorizontalB && ((packedEdgesL & 0x08u) == 0x08u));
|
| +
|
| + ivec2 offsetC;
|
| + uint packedEdgesM1P0;
|
| + uint packedEdgesP1P0;
|
| + if (horizontal) {
|
| + packedEdgesM1P0 = packedEdgesL;
|
| + packedEdgesP1P0 = packedEdgesR;
|
| + offsetC = ivec2(2, 0);
|
| + } else {
|
| + packedEdgesM1P0 = packedEdgesB;
|
| + packedEdgesP1P0 = packedEdgesT;
|
| + offsetC = ivec2(0, 2);
|
| + }
|
|
|
| - // 3.) Completely surrounded with edges from all 4 sides
|
| - if (numberOfEdges == 4.0) {
|
| - // with value of 0.07, the pixel will retain 78% of its colour
|
| - // and the remaining 22% will come from its 4 neighbours (which
|
| - // are unlikely to be blurred)
|
| - blurCoeff = 0.07;
|
| + uvec4 edgesM1P0 = UnpackEdge(packedEdgesM1P0);
|
| + uvec4 edgesP1P0 = UnpackEdge(packedEdgesP1P0);
|
| + uvec4 edgesP2P0 = UnpackEdge(uint(
|
| + texelFetch(g_src0TextureFlt, screenPosI.xy + offsetC, 0).r *
|
| + 255.5));
|
| +
|
| + uvec4 arg0;
|
| + uvec4 arg1;
|
| + uvec4 arg2;
|
| + uvec4 arg3;
|
| + bool arg4;
|
| +
|
| + if (horizontal) {
|
| + arg0 = uvec4(edges);
|
| + arg1 = edgesM1P0;
|
| + arg2 = edgesP1P0;
|
| + arg3 = edgesP2P0;
|
| + arg4 = true;
|
| + } else {
|
| + // Reuse the same code for vertical (used for horizontal above)
|
| + // but rotate input data 90º counter-clockwise.
|
| + // See FindLineLength()
|
| + // e.g. arg0.r (new top) must be mapped to edges.g (old top)
|
| + arg0 = uvec4(edges.gbar);
|
| + arg1 = edgesM1P0.gbar;
|
| + arg2 = edgesP1P0.gbar;
|
| + arg3 = edgesP2P0.gbar;
|
| + arg4 = false;
|
| + }
|
| +
|
| + {
|
| + ivec2 screenPos = screenPosI.xy;
|
| + bvec4 _edges = bvec4(arg0);
|
| + bvec4 _edgesM1P0 = bvec4(arg1);
|
| + bvec4 _edgesP1P0 = bvec4(arg2);
|
| + bvec4 _edgesP2P0 = bvec4(arg3);
|
| + bool horizontal = arg4;
|
| +
|
| + // Normal Z case:
|
| + // __ __
|
| + // X|
|
| + // ¯¯ ¯¯
|
| + bool isNormalZ = _edges.r && _edges.g && !_edgesP1P0.r &&
|
| + !_edgesP1P0.g && _edgesP1P0.b && _edgesP1P0.a &&
|
| + !_edgesM1P0.r && _edgesM1P0.g && !_edgesP2P0.b &&
|
| + _edgesP2P0.a;
|
| +
|
| + // Inverted Z case:
|
| + // __ __
|
| + // X|
|
| + // ¯¯ ¯¯
|
| + bool isInvertedZ = _edges.r && _edges.a && !_edgesP1P0.r &&
|
| + _edgesP1P0.g && _edgesP1P0.b &&
|
| + !_edgesP1P0.a && !_edgesM1P0.r &&
|
| + _edgesM1P0.a && _edgesP2P0.g && !_edgesP2P0.b;
|
| +
|
| + bool isZ = isInvertedZ || isNormalZ;
|
| + if (isZ) {
|
| + forFollowUpCoords[forFollowUpCount++] =
|
| + ivec4(screenPosI.xy, horizontal, isInvertedZ);
|
| + }
|
| + }
|
| + }
|
| }
|
|
|
| // |blurCoeff| must be not zero at this point.
|
| vec4 blurMap = xFroms * blurCoeff;
|
| -
|
| vec4 pixelC = texelFetch(g_screenTexture, screenPosI.xy, 0);
|
|
|
| const float centerWeight = 1.0;
|
| @@ -1654,146 +1762,6 @@ const char ApplyFramebufferAttachmentCMAAINTELResourceManager::cmaa_frag_s2_[] =
|
| PackBlurAAInfo(screenPosI.xy, uint(numberOfEdges)));
|
| \n#endif\n
|
| imageStore(g_resultTextureFlt4Slot1, screenPosI.xy, color);
|
| -
|
| - if (numberOfEdges == 2.0) {
|
| - uint packedEdgesL = packedEdgesArray[(0 + _x) * 4 + (1 + _y)];
|
| - uint packedEdgesB = packedEdgesArray[(1 + _x) * 4 + (0 + _y)];
|
| - uint packedEdgesR = packedEdgesArray[(2 + _x) * 4 + (1 + _y)];
|
| - uint packedEdgesT = packedEdgesArray[(1 + _x) * 4 + (2 + _y)];
|
| -
|
| - bool isHorizontalA = ((packedEdgesC) == (0x01u | 0x02u)) &&
|
| - ((packedEdgesR & 0x08u) == 0x08u);
|
| - bool isHorizontalB = ((packedEdgesC) == (0x01u | 0x08u)) &&
|
| - ((packedEdgesR & 0x02u) == 0x02u);
|
| -
|
| - bool isHCandidate = isHorizontalA || isHorizontalB;
|
| -
|
| - bool isVerticalA = ((packedEdgesC) == (0x02u | 0x04u)) &&
|
| - ((packedEdgesT & 0x01u) == 0x01u);
|
| - bool isVerticalB = ((packedEdgesC) == (0x01u | 0x02u)) &&
|
| - ((packedEdgesT & 0x04u) == 0x04u);
|
| - bool isVCandidate = isVerticalA || isVerticalB;
|
| -
|
| - bool isCandidate = isHCandidate || isVCandidate;
|
| -
|
| - if (!isCandidate)
|
| - continue;
|
| -
|
| - bool horizontal = isHCandidate;
|
| -
|
| - // what if both are candidates? do additional pruning (still not
|
| - // 100% but gets rid of worst case errors)
|
| - if (isHCandidate && isVCandidate)
|
| - horizontal =
|
| - (isHorizontalA && ((packedEdgesL & 0x02u) == 0x02u)) ||
|
| - (isHorizontalB && ((packedEdgesL & 0x08u) == 0x08u));
|
| -
|
| - ivec2 offsetC;
|
| - uint packedEdgesM1P0;
|
| - uint packedEdgesP1P0;
|
| - if (horizontal) {
|
| - packedEdgesM1P0 = packedEdgesL;
|
| - packedEdgesP1P0 = packedEdgesR;
|
| - offsetC = ivec2(2, 0);
|
| - } else {
|
| - packedEdgesM1P0 = packedEdgesB;
|
| - packedEdgesP1P0 = packedEdgesT;
|
| - offsetC = ivec2(0, 2);
|
| - }
|
| -
|
| - uvec4 edgesM1P0 = UnpackEdge(packedEdgesM1P0);
|
| - uvec4 edgesP1P0 = UnpackEdge(packedEdgesP1P0);
|
| - uvec4 edgesP2P0 = UnpackEdge(uint(texelFetch(
|
| - g_src0TextureFlt, screenPosI.xy + offsetC, 0).r * 255.5));
|
| -
|
| - uvec4 arg0;
|
| - uvec4 arg1;
|
| - uvec4 arg2;
|
| - uvec4 arg3;
|
| - bool arg4;
|
| -
|
| - if (horizontal) {
|
| - arg0 = uvec4(edges);
|
| - arg1 = edgesM1P0;
|
| - arg2 = edgesP1P0;
|
| - arg3 = edgesP2P0;
|
| - arg4 = true;
|
| - } else {
|
| - // Reuse the same code for vertical (used for horizontal above)
|
| - // but rotate input data 90º counter-clockwise. See FindLineLength()
|
| - // e.g. arg0.r (new top) must be mapped to edges.g (old top)
|
| - arg0 = uvec4(edges.gbar);
|
| - arg1 = edgesM1P0.gbar;
|
| - arg2 = edgesP1P0.gbar;
|
| - arg3 = edgesP2P0.gbar;
|
| - arg4 = false;
|
| - }
|
| -
|
| - {
|
| - ivec2 screenPos = screenPosI.xy;
|
| - uvec4 _edges = arg0;
|
| - uvec4 _edgesM1P0 = arg1;
|
| - uvec4 _edgesP1P0 = arg2;
|
| - uvec4 _edgesP2P0 = arg3;
|
| - bool horizontal = arg4;
|
| -
|
| - // Normal Z case:
|
| - // __
|
| - // X|
|
| - // ¯¯
|
| - bool isInvertedZ = false;
|
| - bool isNormalZ = false;
|
| - {
|
| - \n#ifndef SETTINGS_ALLOW_SHORT_Zs\n
|
| - // (1u-_edges.a) constraint can be removed; it was added for
|
| - // some rare cases
|
| - uint isZShape = _edges.r * _edges.g * _edgesM1P0.g *
|
| - _edgesP1P0.a *_edgesP2P0.a * (1u - _edges.b) *
|
| - (1u - _edgesP1P0.r) * (1u - _edges.a) *
|
| - (1u - _edgesP1P0.g);
|
| - \n#else\n
|
| - uint isZShape = _edges.r * _edges.g * _edgesP1P0.a *
|
| - (1u - _edges.b) * (1u - _edgesP1P0.r) * (1u - _edges.a) *
|
| - (1u - _edgesP1P0.g);
|
| - isZShape *= (_edgesM1P0.g + _edgesP2P0.a);
|
| - // and at least one of these need to be there
|
| - \n#endif\n
|
| - if (isZShape > 0u) {
|
| - isNormalZ = true;
|
| - }
|
| - }
|
| -
|
| - // Inverted Z case:
|
| - // __
|
| - // X|
|
| - // ¯¯
|
| - {
|
| - \n#ifndef SETTINGS_ALLOW_SHORT_Zs\n
|
| - uint isZShape = _edges.r * _edges.a * _edgesM1P0.a *
|
| - _edgesP1P0.g * _edgesP2P0.g * (1u - _edges.b) *
|
| - (1u - _edgesP1P0.r) * (1u - _edges.g) *
|
| - (1u - _edgesP1P0.a);
|
| - \n#else\n
|
| - uint isZShape = _edges.r * _edges.a * _edgesP1P0.g *
|
| - (1u - _edges.b) * (1u - _edgesP1P0.r) * (1u - _edges.g) *
|
| - (1u - _edgesP1P0.a);
|
| - isZShape *=
|
| - (_edgesM1P0.a + _edgesP2P0.g);
|
| - // and at least one of these need to be there
|
| - \n#endif\n
|
| -
|
| - if (isZShape > 0u) {
|
| - isInvertedZ = true;
|
| - }
|
| - }
|
| -
|
| - bool isZ = isInvertedZ || isNormalZ;
|
| - if (isZ) {
|
| - forFollowUpCoords[forFollowUpCount++] =
|
| - ivec4(screenPosI.xy, horizontal, isInvertedZ);
|
| - }
|
| - }
|
| - }
|
| }
|
|
|
| // This code below is the only potential bug with this algorithm :
|
|
|