Bug 70789 - Optimize canvas fills / drawImage when covering entire canvas
Summary: Optimize canvas fills / drawImage when covering entire canvas
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Canvas (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Ben Wells
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-24 17:48 PDT by Ben Wells
Modified: 2011-11-03 18:55 PDT (History)
5 users (show)

See Also:


Attachments
Patch (4.39 KB, patch)
2011-11-02 19:35 PDT, Ben Wells
no flags Details | Formatted Diff | Diff
Patch using FloatQuad (4.34 KB, patch)
2011-11-03 16:26 PDT, Ben Wells
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ben Wells 2011-10-24 17:48:54 PDT
When compositing fills / drawImage calls in canvas, and the composite mode is Source-In, Source-Out, Destination-In, Destination-Atop or Copy, the canvas is cleared. For all of these modes apart from Copy a temporary buffer is also used. If the fill / drawImage is covering the entire canvas we can optimise away the clear and the use of a temporary buffer.
Comment 1 Ben Wells 2011-11-02 19:35:36 PDT
Created attachment 113422 [details]
Patch
Comment 2 Ben Wells 2011-11-02 21:59:27 PDT
It would be nice to do the same optimization for filling a path, but there doesn't seem to be any easy way to see if a path contains a rectangle.
Comment 3 Stephen White 2011-11-03 08:29:35 PDT
Comment on attachment 113422 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=113422&action=review

Looks good.  Thanks for implementing this!  r=me

> Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp:1566
> +    Path transformedPath;
> +    transformedPath.addRect(rect);
> +    transformedPath.transform(state().m_transform);
> +
> +    IntRect canvasRect(0, 0, canvas()->width(), canvas()->height());
> +    return transformedPath.contains(canvasRect.minXMinYCorner()) && transformedPath.contains(canvasRect.minXMaxYCorner())
> +        && transformedPath.contains(canvasRect.maxXMinYCorner()) && transformedPath.contains(canvasRect.maxXMaxYCorner());

This looks fine, but I'm wondering if it would be easier to use FloatQuad:

FloatQuad quad(rect);
FloatQuad canvasQuad(FloatRect(0, 0, canvas->width(), canvas->height()));
return state().m_transform.mapQuad(quad).containsQuad(canvasQuad);

OTOH, I've never actually tried it, so feel free to go with what you've already got.
Comment 4 Ben Wells 2011-11-03 16:26:59 PDT
Created attachment 113571 [details]
Patch using FloatQuad
Comment 5 Ben Wells 2011-11-03 16:38:41 PDT
Comment on attachment 113571 [details]
Patch using FloatQuad

Using FloatQuad is much nicer. Thanks for the tip!
Comment 6 Stephen White 2011-11-03 18:24:01 PDT
Comment on attachment 113571 [details]
Patch using FloatQuad

Looks great.  r=me
Comment 7 WebKit Review Bot 2011-11-03 18:55:45 PDT
Comment on attachment 113571 [details]
Patch using FloatQuad

Clearing flags on attachment: 113571

Committed r99257: <http://trac.webkit.org/changeset/99257>
Comment 8 WebKit Review Bot 2011-11-03 18:55:50 PDT
All reviewed patches have been landed.  Closing bug.