Closed Bug 1120294 Opened 5 years ago Closed 5 years ago

Use A8 format surface to store svg mask

Categories

(Core :: SVG, defect)

x86
macOS
defect
Not set

Tracking

()

RESOLVED FIXED
mozilla38

People

(Reporter: ethlin, Assigned: ethlin)

References

Details

Attachments

(2 files, 4 obsolete files)

Use a A8 format surface to store svg mask. It could benefit the performance of apply mask and we should only set the alpha channel when calculating mask.
Attached patch bug_1120294.patch (obsolete) — Splinter Review
Create a A8 format surface to store the svg mask. We still need the original ARGB buffer, but the new A8 mask could reduce the time of mask applying. I also change the memset action of each luminance calculation function, so we only need to do the 1/4 memset now.
Attachment #8547353 - Flags: feedback?(hshih)
Comment on attachment 8547353 [details] [diff] [review]
bug_1120294.patch

> 
> static void
>-ComputesRGBLuminanceMask(uint8_t *aData,
>-                         int32_t aStride,
>+ComputesRGBLuminanceMask(uint8_t *aSrcData,

can we have aSrcData be a const pointer in every case and not modify the source pixels? 
Same comment applies to every method.

>+                         int32_t aSrcStride,
>+                         uint8_t *aDstData,
>+                         int32_t aDstStride,
>                          const IntSize &aSize,
>                          float aOpacity)
> {
> 
>+  // Create a aplha channel mask for output

s/a aplha/an alpha/
Thanks for the suggestions. I tried to use const srcData, but I couldn't send const pointer to ComputeLinearRGBLuminanceMask because there is some alpha calculations. For the other two functions, I still use const pointer. I also enhance the neon part that we can use neon to do the alpha checking.
Attachment #8547353 - Attachment is obsolete: true
Attachment #8547353 - Flags: feedback?(hshih)
Attachment #8547495 - Flags: feedback?(longsonr)
Previous patch is wrong. Update a new patch.
Attachment #8547495 - Attachment is obsolete: true
Attachment #8547495 - Flags: feedback?(longsonr)
Attachment #8547500 - Flags: feedback?(longsonr)
Comment on attachment 8547495 [details] [diff] [review]
v1 - use a8 surface and modify neon code for svg

Review of attachment 8547495 [details] [diff] [review]:
-----------------------------------------------------------------

Some comments apply in many places. Overall this is in pretty good shape though. I only give it a - as I want to see the new version.

::: layout/svg/nsSVGMaskFrame.cpp
@@ +135,1 @@
>          }

Copy the 4 srcPixels into a uint32_t then change that.

@@ +145,1 @@
>                          blueFactor) >> 8) * (a / 255.0f));

And work with the copy here.

@@ +276,5 @@
>    RefPtr<DataSourceSurface> maskSurface = maskSnapshot->GetDataSurface();
>    DataSourceSurface::MappedSurface map;
>    if (!maskSurface->Map(DataSourceSurface::MapType::READ_WRITE, &map)) {
>      return nullptr;
>    }

We really want this to be MapType::READ

@@ +281,5 @@
>  
> +  // Create a alpha channel mask for output
> +  RefPtr<DrawTarget> dstMaskDT =
> +    Factory::CreateDrawTarget(BackendType::CAIRO, maskSurfaceSize,
> +                              SurfaceFormat::A8);

dest is clearer than dst

::: layout/svg/nsSVGMaskFrameNEON.cpp
@@ +31,5 @@
>    uint8x8_t redVec = vdup_n_u8(redFactor);
>    uint8x8_t greenVec = vdup_n_u8(greenFactor);
>    uint8x8_t blueVec = vdup_n_u8(blueFactor);
> +  uint8x8_t zeroVec = vdup_n_u8(0);
> +  uint8x8_t oneVec = vdup_n_u8(1);

I'd rather we used Vector than Vec. Abbreviations are really not useful as a coding style.

@@ +47,5 @@
> +      gray = vmul_u8(gray, vand_u8(alphaVec, oneVec));
> +
> +      // Put the result to the 8 pixels
> +      vst1_u8(dstPixel, gray);
> +      srcPixel += 8 * 4;

* sizeof srcPixel[0] is clearer than the magic 4

@@ +53,3 @@
>      }
>  
> +    // Calculate the reset pixels of the line by cpu

reset? Shouldn't this be Calculate the rest of the pixels...

@@ +56,5 @@
>      for (int32_t x = 0; x < remainderWidth; x++) {
> +      if (srcPixel[GFX_ARGB32_OFFSET_A] > 0) {
> +        dstPixel[0] = (redFactor * srcPixel[GFX_ARGB32_OFFSET_R]+
> +                       greenFactor * srcPixel[GFX_ARGB32_OFFSET_G] +
> +                       blueFactor * srcPixel[GFX_ARGB32_OFFSET_B]) >> 8;

I'd prefer *dstPixel to dstPixel[0] but I don't really mind if you want to leave it as is.

@@ +60,5 @@
> +                       blueFactor * srcPixel[GFX_ARGB32_OFFSET_B]) >> 8;
> +      } else {
> +        dstPixel[0] = 0;
> +      }
> +      srcPixel += 4;

sizeof would be clearer

::: layout/svg/nsSVGMaskFrameNEON.h
@@ +15,2 @@
>                                int32_t aStride,
> +                              uint8_t *aDstData,

Make these aSrcData and aSrcStride or better yet change everything to aSourceData, aSourceStride, aDestData and aDestStride.
Attachment #8547495 - Attachment is obsolete: false
Attachment #8547495 - Attachment is obsolete: true
I've reviewed the wrong patch then. Can you apply the review comments anyway and I'll rereview once you've done that.
Attachment #8547500 - Flags: feedback?(longsonr)
Thanks for the comments. I applied most of the comments, but I cannot replace the magic number 4 with sizeof(sourcePixel[0]) because the type of sourcePixel is uint8_t. Most places are using the the magic number now. This may be another issue for reducing the magic number.
Attachment #8547500 - Attachment is obsolete: true
Attachment #8547601 - Flags: review?(longsonr)
Attachment #8547601 - Flags: review?(longsonr) → review+
Comment on attachment 8547601 [details] [diff] [review]
v1 - use a8 surface and modify neon code for svg

>       if (a) {
>+        uint8_t tempPixel[4];
>+        memcpy(tempPixel, sourcePixel, 4);

move the memcpy into an else case of the if below.

>         if (a != 255) {
>-          pixel[GFX_ARGB32_OFFSET_B] =
>-            (255 * pixel[GFX_ARGB32_OFFSET_B]) / a;
>-          pixel[GFX_ARGB32_OFFSET_G] =
>-            (255 * pixel[GFX_ARGB32_OFFSET_G]) / a;
>-          pixel[GFX_ARGB32_OFFSET_R] =
>-            (255 * pixel[GFX_ARGB32_OFFSET_R]) / a;
>+          tempPixel[GFX_ARGB32_OFFSET_B] =
>+            (255 * tempPixel[GFX_ARGB32_OFFSET_B]) / a;
>+          tempPixel[GFX_ARGB32_OFFSET_G] =
>+            (255 * tempPixel[GFX_ARGB32_OFFSET_G]) / a;
>+          tempPixel[GFX_ARGB32_OFFSET_R] =
>+            (255 * tempPixel[GFX_ARGB32_OFFSET_R]) / a;

and use sourcePixel as the source here, thereby avoiding the memcpy in the if case.

>         }
>
Attached patch v2 - Reduce the chance of memcpy (obsolete) — Splinter Review
This patch apply the comment that checking the alpha to reduce the chance of memory copy.
Attachment #8547881 - Flags: review?(longsonr)
Comment on attachment 8547881 [details] [diff] [review]
v2 - Reduce the chance of memcpy

>+          uint8_t tempPixel[4];
>+          memcpy(tempPixel, sourcePixel, 4);

You don't need the memcpy

>           tempPixel[GFX_ARGB32_OFFSET_B] =
>             (255 * tempPixel[GFX_ARGB32_OFFSET_B]) / a;
>           tempPixel[GFX_ARGB32_OFFSET_G] =
>             (255 * tempPixel[GFX_ARGB32_OFFSET_G]) / a;
>           tempPixel[GFX_ARGB32_OFFSET_R] =
>             (255 * tempPixel[GFX_ARGB32_OFFSET_R]) / a;

If you change tempPixel to sourcePixel after each = here.

>+          /* sRGB -> linearRGB -> intensity */
>+          *destPixel =
>+            static_cast<uint8_t>
>+                       (((gsRGBToLinearRGBMap[tempPixel[GFX_ARGB32_OFFSET_R]] *
>+                          redFactor +
>+                          gsRGBToLinearRGBMap[tempPixel[GFX_ARGB32_OFFSET_G]] *
>+                          greenFactor +
>+                          gsRGBToLinearRGBMap[tempPixel[GFX_ARGB32_OFFSET_B]] *
>+                          blueFactor) >> 8) * (a / 255.0f));
>+        }
Attachment #8547881 - Flags: review?(longsonr) → review+
I misunderstand the meaning. I think this patch should be correct.
Attachment #8547881 - Attachment is obsolete: true
Attachment #8547961 - Flags: review?(longsonr)
Attachment #8547961 - Flags: review?(longsonr) → review+
The folks who do checkin-needed do like a checkin comments with r= on them. In this case r=longsonr
Blocks: 1121869
You need to log in before you can comment on or make changes to this bug.