Closed Bug 830734 Opened 11 years ago Closed 10 years ago

Implement Path primitives

Categories

(Core :: Graphics: Canvas2D, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla31

People

(Reporter: tschneider, Assigned: cabanier)

References

(Blocks 1 open bug)

Details

(Keywords: dev-doc-complete, Whiteboard: [Shumway:p1])

Attachments

(2 files, 20 obsolete files)

6.35 KB, patch
roc
: review+
Details | Diff | Splinter Review
16.79 KB, patch
roc
: review+
Details | Diff | Splinter Review
Canvas v5 introduces a bunch of useful API additions. We are working on Shumway, a SWF runtime written in JavaScript, that uses Canvas for rendering. One of the new features we (and other apps like Pdf.js and Games in general) would profit a lot from is support for Path primitives (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path-objects). At the moment we use a shim for exactly that API and implementing it native definitely makes sense for us.
Do you have any comments on: http://lists.w3.org/Archives/Public/public-canvas-api/2013JanMar/0002.html
Basically, your implementation would be the pathSink (naming is TBD)
Can we not share more code with our SVG SVGPathData::ConstructPath implementation rather than writing yet another path constructor?
Attachment #702330 - Attachment is obsolete: true
We are also working on adding the path object to WebKit: https://bugs.webkit.org/show_bug.cgi?id=97333
This will live behind an experimental flag for now. Please note that it will be different from the current WhatWG proposal. It would be good if we can coordinate this.
(In reply to Rik Cabanier from comment #5)
> We are also working on adding the path object to WebKit:
> https://bugs.webkit.org/show_bug.cgi?id=97333
> This will live behind an experimental flag for now. Please note that it will
> be different from the current WhatWG proposal. It would be good if we can
> coordinate this.

Did you send use cases to the list? If not, I suggest we implement the spec and you fix your implementation.
I did. There was no substantial feedback so we're trying to fix it in the implementation. Ian indicated in the bug that he would update the spec.

The current path syntax is broken. Simply aggregating path segments is the wrong way to do path logic and will give bad results.
We already use a shim for the Path API in Shumway (Flash VM in JavaScript) and we haven't encountered any major problems with the current spec so far. Not exactly sure what your concerns are.
That's because flash's edge lists already separate the paths into non-intersecting regions. In addition, Flash Authoring (which is the biggest producer of SWFs) will remove shared lines which also fixes even-odd weirdness for you.
This is not something that an author could do.

I would be very surprised if you can use this to implement stroking reliably.
Any real world examples that proof your point?
s/proof/prove/
(In reply to Tobias Schneider from comment #10)
> Any real world examples that proof your point?

I have a blog post that shows the problem. I'm waiting for my team to sign off on it.
> I have a blog post that shows the problem. I'm waiting for my team to sign
> off on it.

Cool.

For now I've implemented just as much of the API as WebKit does (plus the ability to parse an optional given SVG path data string). That's what you named PathSink. I'm not going to implement any of the Path interface methods (addPath, addPathByStrokingPath...) in this step. So no conflicts to API's that might change.
Attachment #705958 - Flags: review?(jmuizelaar)
Comment on attachment 705958 [details] [diff] [review]
Initial implementation of Path primitives. v2

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

This should be building an Azure Path object directly instead of building a temporary Canvas path object and building a Path from that during Stroke/Fill etc.
Attachment #705958 - Flags: review?(jmuizelaar) → review-
Whiteboard: [Shumway:p1]
Blocks: 885526
Blocks: 927828
No longer blocks: 927828
Blocks: 927828
Let's make this happen!
(In reply to Jeff Muizelaar [:jrmuizel] on PTO till October 21 from comment #14)
> Comment on attachment 705958 [details] [diff] [review]
> Initial implementation of Path primitives. v2
> 
> Review of attachment 705958 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> This should be building an Azure Path object directly instead of building a
> temporary Canvas path object and building a Path from that during
> Stroke/Fill etc.

I think this was done because the Path object doesn't know what type of backend the canvas object will have.
I've revived this patch and will try to land it.

Should I update it to create an azure path?
Depends on: 929723
Assignee: nobody → cabanier
Attachment #705958 - Attachment is obsolete: true
Attachment #822115 - Attachment description: canvaspath.patch → Refreshed patch that incorporates jeff's comment
Comment on attachment 822115 [details] [diff] [review]
Refreshed patch that incorporates jeff's comment

Try build: https://tbpl.mozilla.org/?tree=Try&rev=0879372fd3ec

Need to patch the test that finds the new global class. maybe add more tests?
Attachment #822115 - Flags: feedback?(roc)
Blocks: 931587
Attachment #822115 - Flags: feedback?(roc) → review?(roc)
Comment on attachment 822115 [details] [diff] [review]
Refreshed patch that incorporates jeff's comment

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

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +1838,5 @@
>  
> +already_AddRefed<CanvasPath>
> +CanvasRenderingContext2D::CurrentPath()
> +{
> +  RefPtr<PathBuilder> CopyPathBuilder;

copyPathBuilder

@@ +1851,5 @@
> +    mDSPathBuilder = mTempPath->CopyToBuilder(CurrentState().fillRule);
> +  }
> +
> +  nsRefPtr<CanvasPath> NewPathObject(new CanvasPath(this, CopyPathBuilder));
> +  return NewPathObject.forget();

newPathObject

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +24,5 @@
>  #include "gfx2DGlue.h"
>  #include "imgIEncoder.h"
>  
> +#define NS_CANVASPATHAZURE_PRIVATE_IID \
> +    {0xaf712aac, 0xfd0b, 0x4cea, {0x9f, 0xa4, 0x83, 0x02, 0x87, 0x4f, 0x7a, 0x18}}

We shouldn't need this.

@@ +45,5 @@
>  
>  template<typename T> class Optional;
>  
> +class CanvasPath :
> +  public nsIDOMPath,

We shouldn't need to inherit from nsIDOMPath here. We shouldn't need nsIDOMPath at all.

@@ +52,5 @@
> +public:
> +  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATHAZURE_PRIVATE_IID)
> +
> +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
> +  NS_DECL_CYCLE_COLLECTION_CLASS(CanvasPath)

You don't need to implement nsISupports. Follow CanvasPattern and use   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPattern).

@@ +76,5 @@
> +             mozilla::ErrorResult& error);
> +  void Rect(double x, double y, double w, double h);
> +  void Arc(double x, double y, double radius,
> +           double startAngle, double endAngle, bool anticlockwise,
> +           mozilla::ErrorResult& error);

You should already be in the mozilla namespace so don't use the mozilla prefix here.

@@ +83,5 @@
> +  void BezierTo(const mozilla::gfx::Point& aCP1,
> +                const mozilla::gfx::Point& aCP2,
> +                const mozilla::gfx::Point& aCP3);
> +
> +  CanvasPath(nsISupports* aParent, mozilla::RefPtr<mozilla::gfx::PathBuilder> mPathBuilder);

Use typedefs in the class to avoid using prefixes here. E.g.
  typedef mozilla::gfx::PathBuilder PathBuilder;
  typedef mozilla::gfx::Float Float;
You don't need the mozilla prefix in any case.

@@ +376,5 @@
>    void Rect(double x, double y, double w, double h);
>    void Arc(double x, double y, double radius, double startAngle,
>             double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
>  
> +  already_AddRefed<CanvasPath > CurrentPath();

Remove space before >

::: dom/base/nsDOMClassInfo.cpp
@@ +87,5 @@
>  // Event related includes
>  #include "nsIDOMEventTarget.h"
>  
> +// Canvas
> +#include "nsIDOMCanvasRenderingContext2D.h"

No changes to nsDOMClassInfo should be needed. nsDOMClassInfo is obsolete.

::: dom/base/nsDOMClassInfoClasses.h
@@ +25,5 @@
>  
>  // Range classes
>  DOMCI_CLASS(Selection)
>  
> +DOMCI_CLASS(CanvasPath)

This shouldn't be needed. nsDOMClassInfoClasses is obsolete.

::: dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
@@ +32,5 @@
>    const unsigned long DRAWWINDOW_ASYNC_DECODE_IMAGES = 0x10;
>  };
> +
> +[scriptable, uuid(1146b8a4-45b4-4c96-8817-d55647f31e15)]
> +interface nsIDOMPath : nsISupports

I don't think we want to add this. nsIDOMCanvasRenderingContext2D.idl is obsolete.

::: dom/webidl/CanvasRenderingContext2D.webidl
@@ +123,5 @@
>    [Throws]
>    void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
>  
> +  // current path 
> +  attribute Path currentPath;

Is this specced somewhere? Because I don't see it in http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html.

::: js/xpconnect/src/dom_quickstubs.qsconf
@@ +52,5 @@
>      # dom/interfaces/core
>      'nsIDOMDOMStringList.*',
>  
> +    #
> +    'nsIDOMPath.*',

You shouldn't be adding anything to dom_quickstubs.qsconf. This is all obseleted by .webidl.
Thanks for the review.
Most of that code came from the old patch. I will update per your comments.
Attached patch New patch for path objects (obsolete) — Splinter Review
Attachment #822115 - Attachment is obsolete: true
Attachment #822115 - Flags: review?(roc)
Comment on attachment 822115 [details] [diff] [review]
Refreshed patch that incorporates jeff's comment

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

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +1838,5 @@
>  
> +already_AddRefed<CanvasPath>
> +CanvasRenderingContext2D::CurrentPath()
> +{
> +  RefPtr<PathBuilder> CopyPathBuilder;

Fixed.

@@ +1851,5 @@
> +    mDSPathBuilder = mTempPath->CopyToBuilder(CurrentState().fillRule);
> +  }
> +
> +  nsRefPtr<CanvasPath> NewPathObject(new CanvasPath(this, CopyPathBuilder));
> +  return NewPathObject.forget();

Fixed

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +24,5 @@
>  #include "gfx2DGlue.h"
>  #include "imgIEncoder.h"
>  
> +#define NS_CANVASPATHAZURE_PRIVATE_IID \
> +    {0xaf712aac, 0xfd0b, 0x4cea, {0x9f, 0xa4, 0x83, 0x02, 0x87, 0x4f, 0x7a, 0x18}}

You were right.
Removed this + all other obsolete code

@@ +76,5 @@
> +             mozilla::ErrorResult& error);
> +  void Rect(double x, double y, double w, double h);
> +  void Arc(double x, double y, double radius,
> +           double startAngle, double endAngle, bool anticlockwise,
> +           mozilla::ErrorResult& error);

removed the prefix everywhere in the file.

@@ +376,5 @@
>    void Rect(double x, double y, double w, double h);
>    void Arc(double x, double y, double radius, double startAngle,
>             double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
>  
> +  already_AddRefed<CanvasPath > CurrentPath();

done
Attachment #824467 - Flags: review?(roc)
Comment on attachment 824467 [details] [diff] [review]
New patch for path objects

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

I still don't see a spec for currentPath anywhere!

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +42,5 @@
>  
>  template<typename T> class Optional;
>  
> +class BaseCanvasPath
> +{

I don't understand why you've separated things into this base class. Can't we just merge this into CanvasPath?

::: dom/bindings/Bindings.conf
@@ +1876,5 @@
>  addExternalIface('CameraReleaseCallback', nativeType='nsICameraReleaseCallback', headerFile='nsIDOMCameraManager.h')
>  addExternalIface('CameraStartRecordingCallback', nativeType='nsICameraStartRecordingCallback', headerFile='nsIDOMCameraManager.h')
>  addExternalIface('CameraPreviewStateChange', nativeType='nsICameraPreviewStateChange', headerFile='nsIDOMCameraManager.h')
>  addExternalIface('CameraPreviewStreamCallback', nativeType='nsICameraPreviewStreamCallback', headerFile='nsIDOMCameraManager.h')
> +addExternalIface('CameraRecorderStateChange', nativeType='nsICameraRecorderStateChange', headerFile='nsIDOMCameraManager.h')

There should be no change here.

::: dom/tests/mochitest/general/test_interfaces.html
@@ +104,5 @@
>      "CameraCapabilities",
>      "CameraControl",
>      "CameraManager",
>      "CanvasGradient",
> +    "CanvasPath",

This should not be here.
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #23)
> Comment on attachment 824467 [details] [diff] [review]
> New patch for path objects
> 
> Review of attachment 824467 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> I still don't see a spec for currentPath anywhere!

True. Blink and WebKit implemented it but it's not in the spec yet.
I'll follow up.

> 
> ::: content/canvas/src/CanvasRenderingContext2D.h
> @@ +42,5 @@
> >  
> >  template<typename T> class Optional;
> >  
> > +class BaseCanvasPath
> > +{
> 
> I don't understand why you've separated things into this base class. Can't
> we just merge this into CanvasPath?

I did that because the cleanup patch uses the same base functionality but not the JS exposed logic.
If that one doesn't go anywhere, I can put it back together.

> 
> ::: dom/bindings/Bindings.conf
> @@ +1876,5 @@
> >  addExternalIface('CameraReleaseCallback', nativeType='nsICameraReleaseCallback', headerFile='nsIDOMCameraManager.h')
> >  addExternalIface('CameraStartRecordingCallback', nativeType='nsICameraStartRecordingCallback', headerFile='nsIDOMCameraManager.h')
> >  addExternalIface('CameraPreviewStateChange', nativeType='nsICameraPreviewStateChange', headerFile='nsIDOMCameraManager.h')
> >  addExternalIface('CameraPreviewStreamCallback', nativeType='nsICameraPreviewStreamCallback', headerFile='nsIDOMCameraManager.h')
> > +addExternalIface('CameraRecorderStateChange', nativeType='nsICameraRecorderStateChange', headerFile='nsIDOMCameraManager.h')
> 
> There should be no change here.
> 
> ::: dom/tests/mochitest/general/test_interfaces.html
> @@ +104,5 @@
> >      "CameraCapabilities",
> >      "CameraControl",
> >      "CameraManager",
> >      "CanvasGradient",
> > +    "CanvasPath",
> 
> This should not be here.
Will do
Comment on attachment 824467 [details] [diff] [review]
New patch for path objects

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

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4034,5 @@
> +  return PathBinding::Wrap(cx, scope, this);
> +}
> +
> +already_AddRefed<CanvasPath>
> +CanvasPath::Constructor(const GlobalObject& aGlobal, ErrorResult& rv)

aRv, also elsewhere

@@ +4084,5 @@
> +}
> +
> +void
> +BaseCanvasPath::BezierCurveTo(double cp1x, double cp1y,
> +                          double cp2x, double cp2y,

Indentation

@@ +4088,5 @@
> +                          double cp2x, double cp2y,
> +                          double x, double y)
> +{
> +  BezierTo(mozilla::gfx::Point(ToFloat(cp1x), ToFloat(cp1y)),
> +             mozilla::gfx::Point(ToFloat(cp2x), ToFloat(cp2y)),

Indentation

@@ +4202,5 @@
> +
> +  return mTempPath->CopyToBuilder();
> +}
> +
> +}

} // namespace foo

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +73,5 @@
> +
> +  RefPtr<gfx::PathBuilder> mPathBuilder;
> +};
> +
> +class CanvasPath :

Why is this not called mozilla::dom::Path?

@@ +83,5 @@
> +  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
> +
> +  nsISupports* GetParentObject() { return mParent; }
> +
> +  JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> scope);

* goes to the left, argument names start with a

@@ +91,5 @@
> +  static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
> +                                                  CanvasPath& aCanvasPath,
> +                                                  ErrorResult& rv);
> +
> +  CanvasPath(nsISupports* aParent, RefPtr<gfx::PathBuilder> mPathBuilder);

Passing refptrs as arguments isn't done.

@@ +97,5 @@
> +  CanvasPath(nsISupports* aParent);
> +
> +  virtual ~CanvasPath() {}
> +
> +  nsISupports* mParent;

What keeps this alive?

@@ +629,5 @@
>    /**
>      * Returns the surface format this canvas should be allocated using. Takes
>      * into account mOpaque, platform requirements, etc.
>      */
> +  gfx::SurfaceFormat GetSurfaceFormat() const;

Put all those changes in a separate patch, please.

::: content/canvas/test/test_canvas.html
@@ +24990,5 @@
>    throw e;
>    ok(false, "unexpected exception thrown in: test_linedash");
>   }
>   try {
> +  test_path

You're not running the test. As I asked you before, though, please put this in a separate file.

::: dom/bindings/Bindings.conf
@@ +877,5 @@
>  },
>  
> +'Path': {
> +    'nativeType': 'mozilla::dom::CanvasPath',
> +    'headerFile': 'nsIDOMCanvasRenderingContext2D.h'

That's not true.
Comment on attachment 824467 [details] [diff] [review]
New patch for path objects

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

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +73,5 @@
> +
> +  RefPtr<gfx::PathBuilder> mPathBuilder;
> +};
> +
> +class CanvasPath :

To avoid clashes with Path

@@ +83,5 @@
> +  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
> +
> +  nsISupports* GetParentObject() { return mParent; }
> +
> +  JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> scope);

fixed

@@ +91,5 @@
> +  static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
> +                                                  CanvasPath& aCanvasPath,
> +                                                  ErrorResult& rv);
> +
> +  CanvasPath(nsISupports* aParent, RefPtr<gfx::PathBuilder> mPathBuilder);

fixed

@@ +97,5 @@
> +  CanvasPath(nsISupports* aParent);
> +
> +  virtual ~CanvasPath() {}
> +
> +  nsISupports* mParent;

fixed by wrapping

@@ +629,5 @@
>    /**
>      * Returns the surface format this canvas should be allocated using. Takes
>      * into account mOpaque, platform requirements, etc.
>      */
> +  gfx::SurfaceFormat GetSurfaceFormat() const;

made these changes because roc said to do so. I can remove if needed.
Comment on attachment 824467 [details] [diff] [review]
New patch for path objects

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

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +42,5 @@
>  
>  template<typename T> class Optional;
>  
> +class BaseCanvasPath
> +{

I collapsed them again
(In reply to Rik Cabanier from comment #26)
> @@ +629,5 @@
> >    /**
> >      * Returns the surface format this canvas should be allocated using. Takes
> >      * into account mOpaque, platform requirements, etc.
> >      */
> > +  gfx::SurfaceFormat GetSurfaceFormat() const;
> 
> made these changes because roc said to do so. I can remove if needed.

Don't revert them, but create two patches: one that just removes the prefixes, and another on top of that that contains the functional changes.
Attached patch New patch for path objects (obsolete) — Splinter Review
Attachment #824467 - Attachment is obsolete: true
Attachment #824467 - Flags: review?(roc)
Attachment #826170 - Flags: review?(roc)
(In reply to :Ms2ger from comment #28)
> (In reply to Rik Cabanier from comment #26)
> > @@ +629,5 @@
> > >    /**
> > >      * Returns the surface format this canvas should be allocated using. Takes
> > >      * into account mOpaque, platform requirements, etc.
> > >      */
> > > +  gfx::SurfaceFormat GetSurfaceFormat() const;
> > 
> > made these changes because roc said to do so. I can remove if needed.
> 
> Don't revert them, but create two patches: one that just removes the
> prefixes, and another on top of that that contains the functional changes.

OK. Latest patch doesn't have the changes. Will add another patch with them when I get r+ on this one.
Comment on attachment 826170 [details] [diff] [review]
New patch for path objects

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

::: content/canvas/test/test_canvas.html
@@ +24909,5 @@
>    ok(false, "unexpected exception thrown in: test_linedash");
>   }
>   try {
> +  test_path();
> +  } catch(e) {

Fix indent.

::: dom/webidl/CanvasRenderingContext2D.webidl
@@ +122,5 @@
>    [Throws]
>    void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
>  
> +  // current path
> +  attribute Path currentPath;

I thought you were going to take this out?
Attachment #826170 - Flags: review?(roc) → review-
Comment on attachment 826170 [details] [diff] [review]
New patch for path objects

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

::: content/canvas/test/test_canvas.html
@@ +24909,5 @@
>    ok(false, "unexpected exception thrown in: test_linedash");
>   }
>   try {
> +  test_path();
> +  } catch(e) {

will do.

::: dom/webidl/CanvasRenderingContext2D.webidl
@@ +122,5 @@
>    [Throws]
>    void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
>  
> +  // current path
> +  attribute Path currentPath;

The tests won't work without it. Basically, the path object is useless without a connection to canvas.

I will see if the mailing list converges this week.
If not, I will take it out and just test if the path APIs work.
It it does, I will put the new API behind a runtime flag.
FWIW, for other work I'm implementing code that allows streaming the contents of a Path object to an arbitrary PathSink.
(In reply to Bas Schouten (:bas.schouten) from comment #33)
> FWIW, for other work I'm implementing code that allows streaming the
> contents of a Path object to an arbitrary PathSink.

Like this: https://bugzilla.mozilla.org/show_bug.cgi?id=929723
Comment on attachment 826170 [details] [diff] [review]
New patch for path objects

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

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4020,5 @@
> +{
> +  SetIsDOMBinding();
> +
> +  BackendType aBackend = gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
> +  RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);

I believe we don't have need for creating a draw target to create a path builder anymore. That should be fixed as we don't want to create a DrawTarget for every path.

Also, does the code handle the cases where DrawTarget backends don't match?(i.e. Direct2D vs software when the canvas is too large) I didn't see any tests for that.
Attachment #826170 - Flags: review-
(In reply to Jeff Muizelaar [:jrmuizel] from comment #35)
> Comment on attachment 826170 [details] [diff] [review]
> New patch for path objects
> 
> Review of attachment 826170 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: content/canvas/src/CanvasRenderingContext2D.cpp
> @@ +4020,5 @@
> > +{
> > +  SetIsDOMBinding();
> > +
> > +  BackendType aBackend = gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
> > +  RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);
> 
> I believe we don't have need for creating a draw target to create a path
> builder anymore. That should be fixed as we don't want to create a
> DrawTarget for every path.

Can you point me to the API that allows this?

> 
> Also, does the code handle the cases where DrawTarget backends don't
> match?(i.e. Direct2D vs software when the canvas is too large) I didn't see
> any tests for that.

Did Bas land that code? If so, can you point me to it?
Flags: needinfo?(jmuizelaar)
I'm in the process of:
- renaming path to path2d
- changing currentPath to set/getCurrentPath

Looking at the architecture of mozilla's canvas implementation, I think it would really benefit from having the Shape class (http://blogs.adobe.com/webplatform/2013/01/31/revised-canvas-paths/) since it allows caching of the mPathBuilder object.
What should I do to implement this? It could be behind a runtime flag for now.
(In reply to Rik Cabanier from comment #36)
> (In reply to Jeff Muizelaar [:jrmuizel] from comment #35)
> > 
> > I believe we don't have need for creating a draw target to create a path
> > builder anymore. That should be fixed as we don't want to create a
> > DrawTarget for every path.
> 
> Can you point me to the API that allows this?

There's no current API for this. It would need to be created but should be relatively easy now.

> > 
> > Also, does the code handle the cases where DrawTarget backends don't
> > match?(i.e. Direct2D vs software when the canvas is too large) I didn't see
> > any tests for that.
> 
> Did Bas land that code? If so, can you point me to it?

http://dxr.mozilla.org/mozilla-central/source/gfx/thebes/gfxPlatform.cpp?from=CreateOffscreenCanvasDrawTarget#1004
Flags: needinfo?(jmuizelaar)
(In reply to Jeff Muizelaar [:jrmuizel] from comment #38)
> (In reply to Rik Cabanier from comment #36)
> > (In reply to Jeff Muizelaar [:jrmuizel] from comment #35)
> > > 
> > > I believe we don't have need for creating a draw target to create a path
> > > builder anymore. That should be fixed as we don't want to create a
> > > DrawTarget for every path.
> > 
> > Can you point me to the API that allows this?
> 
> There's no current API for this. It would need to be created but should be
> relatively easy now.

Could you tell me how I could create such an API?
 
> > > 
> > > Also, does the code handle the cases where DrawTarget backends don't
> > > match?(i.e. Direct2D vs software when the canvas is too large) I didn't see
> > > any tests for that.
> > 
> > Did Bas land that code? If so, can you point me to it?
> 
> http://dxr.mozilla.org/mozilla-central/source/gfx/thebes/gfxPlatform.
> cpp?from=CreateOffscreenCanvasDrawTarget#1004

I saw other code for streaming to any pathsink. (StreamToSink)
Were you pointing to the code that creates a reusable backend?
Flags: needinfo?(jmuizelaar)
Attachment #826170 - Attachment is obsolete: true
Attachment #8368633 - Attachment description: canvaspath.patch → 1. update IDL + implementation of path primitives
Attached patch 3. Add tests for path objects (obsolete) — Splinter Review
Attachment #8368633 - Flags: review?(jmuizelaar)
Attachment #8383387 - Flags: review?(jmuizelaar)
Flags: needinfo?(jmuizelaar)
Attachment #8368633 - Attachment is obsolete: true
Attachment #8368633 - Flags: review?(jmuizelaar)
Attachment #8383462 - Flags: review?(jmuizelaar)
Attachment #8383462 - Attachment is obsolete: true
Attachment #8383462 - Flags: review?(jmuizelaar)
Attachment #8383499 - Flags: review?(jmuizelaar)
Attachment #8383499 - Attachment is obsolete: true
Attachment #8383499 - Flags: review?(jmuizelaar)
Attachment #8383500 - Flags: review?(jmuizelaar)
Sorry about the noise. Was updating the wrong patch.

try run: https://tbpl.mozilla.org/?tree=Try&rev=18fb9ed6533f
Attachment #8383500 - Attachment is obsolete: true
Attachment #8383500 - Flags: review?(jmuizelaar)
Attachment #8383501 - Flags: review?(jmuizelaar)
fixed issue with test file
Attachment #8383501 - Attachment is obsolete: true
Attachment #8383501 - Flags: review?(jmuizelaar)
Attachment #8383514 - Flags: review?(jmuizelaar)
Attachment #8383514 - Attachment is obsolete: true
Attachment #8383514 - Flags: review?(jmuizelaar)
Attachment #8383982 - Flags: review?(jmuizelaar)
Attachment #8383982 - Flags: review?(jmuizelaar)
Attachment #8383982 - Attachment is obsolete: true
Attachment #8384034 - Flags: review?(jmuizelaar)
Comment on attachment 8384034 [details] [diff] [review]
1. update IDL + implementation of path primitives

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

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4298,5 @@
> +  SetIsDOMBinding();
> +
> +  RefPtr<DrawTarget> aDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(IntSize(8, 8), gfx::SurfaceFormat::B8G8R8X8);
> +  //RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);
> +  mPathBuilder = aDrawTarget->CreatePathBuilder();

There's currently no reason that we need mTarget for CreatePathBuilder anymore. Afaict it can just live off of the Factory. Can you fix this first before this patch? It should make creating this draw target unnecessary.

@@ +4363,5 @@
> +}
> +
> +void
> +CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
> +                  ErrorResult& error)

This seems to duplicate CanvasRenderingContext2D::ArcTo. Is that necessary?
Attachment #8384034 - Flags: review?(jmuizelaar) → review-
(In reply to Jeff Muizelaar [:jrmuizel] from comment #51)
> Comment on attachment 8384034 [details] [diff] [review]
> 1. update IDL + implementation of path primitives
> 
> Review of attachment 8384034 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: content/canvas/src/CanvasRenderingContext2D.cpp
> @@ +4298,5 @@
> > +  SetIsDOMBinding();
> > +
> > +  RefPtr<DrawTarget> aDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(IntSize(8, 8), gfx::SurfaceFormat::B8G8R8X8);
> > +  //RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);
> > +  mPathBuilder = aDrawTarget->CreatePathBuilder();
> 
> There's currently no reason that we need mTarget for CreatePathBuilder
> anymore. Afaict it can just live off of the Factory. Can you fix this first
> before this patch? It should make creating this draw target unnecessary.

sorry, I addressed that in the second patch: 
   RefPtr<DrawTarget> aDrawTarget = gfxPlatform::ScreenReferenceDrawTarget()->CreatePathBuilder();

> @@ +4363,5 @@
> > +}
> > +
> > +void
> > +CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
> > +                  ErrorResult& error)
> 
> This seems to duplicate CanvasRenderingContext2D::ArcTo. Is that necessary?

I didn't see an easy way to simplify this.
I have a proposed patch to simplify the path handling for canvas which will address that problem. See https://bugzilla.mozilla.org/show_bug.cgi?id=931587
Flags: needinfo?(jmuizelaar)
(In reply to Rik Cabanier from comment #52)
> (In reply to Jeff Muizelaar [:jrmuizel] from comment #51)
> > Comment on attachment 8384034 [details] [diff] [review]
> > 1. update IDL + implementation of path primitives
> > 
> > Review of attachment 8384034 [details] [diff] [review]:
> > -----------------------------------------------------------------
> > 
> > ::: content/canvas/src/CanvasRenderingContext2D.cpp
> > @@ +4298,5 @@
> > > +  SetIsDOMBinding();
> > > +
> > > +  RefPtr<DrawTarget> aDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(IntSize(8, 8), gfx::SurfaceFormat::B8G8R8X8);
> > > +  //RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);
> > > +  mPathBuilder = aDrawTarget->CreatePathBuilder();
> > 
> > There's currently no reason that we need mTarget for CreatePathBuilder
> > anymore. Afaict it can just live off of the Factory. Can you fix this first
> > before this patch? It should make creating this draw target unnecessary.
> 
> sorry, I addressed that in the second patch: 
>    RefPtr<DrawTarget> aDrawTarget =
> gfxPlatform::ScreenReferenceDrawTarget()->CreatePathBuilder();

This is still using a DrawTarget to create the path builder. There should be no reason for that.
Flags: needinfo?(jmuizelaar)
Depends on: 978980
Attachment #8384034 - Attachment is obsolete: true
Attachment #8383416 - Attachment is obsolete: true
Attachment #8389441 - Flags: review?(bas)
Attachment #8389445 - Flags: review?(bas)
Attachment #8389450 - Flags: review?(bas)
Attachment #8389441 - Flags: review?(bas) → review?(roc)
Attachment #8389445 - Flags: review?(bas) → review?(roc)
Attachment #8389450 - Flags: review?(bas) → review?(roc)
Comment on attachment 8389441 [details] [diff] [review]
1. update IDL + implementation of path primitives (

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

How does this deal with a mismatch between the canvas DrawTarget backend and the backend used to construct the CanvasPath?

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4332,5 @@
> +void
> +CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
> +                  ErrorResult& error)
> +{
> +  if (radius < 0) {

Any way to share the code copied into this function?

@@ +4436,5 @@
> +  RefPtr<Path> mTempPath = mPathBuilder->Finish();
> +
> +  FillRule fillRule = FillRule::FILL_WINDING;
> +  if(winding == CanvasWindingRule::Evenodd)
> +    fillRule = FillRule::FILL_EVEN_ODD;

space before (, and {} around body

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +87,5 @@
> +  CanvasPath(nsCOMPtr<nsISupports> aParent, RefPtr<gfx::PathBuilder> mPathBuilder);
> +  virtual ~CanvasPath() {}
> +
> +private:
> +  

delete this line
Attachment #8389441 - Flags: review?(roc) → review-
Comment on attachment 8389450 [details] [diff] [review]
2. Recreate path object if backends don't match + add runtime flag + remove creation of drawtarget from path constructor

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

Fold this into part 1!
Attachment #8389450 - Flags: review?(roc) → review-
Comment on attachment 8389441 [details] [diff] [review]
1. update IDL + implementation of path primitives (

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

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4332,5 @@
> +void
> +CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
> +                  ErrorResult& error)
> +{
> +  if (radius < 0) {

Yes,
I opened a "cleanup" bug that will collapse the logic: https://bugzilla.mozilla.org/show_bug.cgi?id=931587
I will tackle that after this goes in. (If you remember, we talked about not keeping 2 paths in the convas context)
Attachment #8389441 - Attachment is obsolete: true
Attachment #8389450 - Attachment is obsolete: true
Attachment #8392595 - Attachment is obsolete: true
Attachment #8389445 - Attachment description: 3. Add tests for path objects → 2. Add tests for path objects
Attachment #8392615 - Flags: review?(roc)
Keywords: checkin-needed
Blocks: 985178
Blocks: 985257
Blocks: 985801
Depends on: 1009685
Depends on: 1135244
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: