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 : |