RESOLVED WONTFIX 82801
Support resetClip() on 2d canvas
https://bugs.webkit.org/show_bug.cgi?id=82801
Summary Support resetClip() on 2d canvas
Dean Jackson
Reported 2012-03-30 16:01:35 PDT
Attachments
Patch (8.68 KB, patch)
2013-07-10 02:44 PDT, Rashmi Shyamasundar
buildbot: commit-queue-
Archive of layout-test-results from webkit-ews-03 for mac-mountainlion (820.98 KB, application/zip)
2013-07-10 07:31 PDT, Build Bot
no flags
Archive of layout-test-results from webkit-ews-12 for mac-mountainlion-wk2 (556.28 KB, application/zip)
2013-07-11 07:22 PDT, Build Bot
no flags
Patch (10.72 KB, patch)
2013-07-12 03:38 PDT, Rashmi Shyamasundar
buildbot: commit-queue-
Radar WebKit Bug Importer
Comment 1 2012-03-30 16:01:48 PDT
Rashmi Shyamasundar
Comment 2 2013-07-05 03:47:30 PDT
I would like to take up this bug. I see that this bug is currently assigned to Mr. Dean Jackson. But, there is no update since "2012-09-11". Hope it is okay with everyone if I submit a patch for this bug.
Rashmi Shyamasundar
Comment 3 2013-07-10 02:44:20 PDT
Build Bot
Comment 4 2013-07-10 07:31:25 PDT
Comment on attachment 206375 [details] Patch Attachment 206375 [details] did not pass mac-ews (mac): Output: http://webkit-queues.appspot.com/results/1050214 New failing tests: inspector/profiler/canvas2d/canvas2d-api-changes.html fast/canvas/canvas-resetClip.html
Build Bot
Comment 5 2013-07-10 07:31:28 PDT
Created attachment 206389 [details] Archive of layout-test-results from webkit-ews-03 for mac-mountainlion The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: webkit-ews-03 Port: mac-mountainlion Platform: Mac OS X 10.8.3
Rik Cabanier
Comment 6 2013-07-10 08:17:34 PDT
(In reply to comment #2) > I would like to take up this bug. I see that this bug is currently assigned to Mr. Dean Jackson. But, there is no update since "2012-09-11". Hope it is okay with everyone if I submit a patch for this bug. The patch looks great. However, the reason this feature was held up is because we didn't know how it could be implemented in Core Graphics which is the backend that Safari uses. Could you take a look there?
Build Bot
Comment 7 2013-07-11 07:22:22 PDT
Comment on attachment 206375 [details] Patch Attachment 206375 [details] did not pass mac-wk2-ews (mac-wk2): Output: http://webkit-queues.appspot.com/results/1010183 New failing tests: fast/canvas/canvas-resetClip.html inspector/profiler/canvas2d/canvas2d-api-changes.html
Build Bot
Comment 8 2013-07-11 07:22:27 PDT
Created attachment 206459 [details] Archive of layout-test-results from webkit-ews-12 for mac-mountainlion-wk2 The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews. Bot: webkit-ews-12 Port: mac-mountainlion-wk2 Platform: Mac OS X 10.8.3
Rashmi Shyamasundar
Comment 9 2013-07-12 00:34:12 PDT
I tried the below approach for implementing resetClip() in case of CG. It is working successfully. Steps :- When resetClip() is called, 1. Save the imageData from canvas imageBuffer 2. Save the GraphicsContextState 3. Clear the canvas buffer. This will delete the buffer and GraphicsContextStateSaver. 4. Copy the saved imageData to a new imageBuffer 5. Set the graphicsContextState to the saved state. GraphicsContextState does not have information about any clip. Code :- void CanvasRenderingContext2D::resetClip() { GraphicsContext* c = drawingContext(); if (!c) return; if (!state().m_invertibleCTM) return; realizeSaves(); #if USE(CAIRO) c->resetClip(); #endif #if USE(CG) IntRect imageDataRect(0, 0, this->canvas()->width(), this->canvas()->height()); RefPtr<Uint8ClampedArray> m_platformSurfaceImage = this->canvas()->buffer()->getUnmultipliedImageData(imageDataRect); GraphicsContextState m_savedState = this->canvas()->drawingContext()->state(); this->canvas()->clearBuffers(); IntPoint destOffset(0, 0); IntSize sourceSize = this->canvas()->size(); IntRect sourceRect(0, 0, sourceSize.width(), sourceSize.height()); this->canvas()->buffer()->putByteArray(Unmultiplied, m_platformSurfaceImage.get(), sourceSize, sourceRect, destOffset); m_platformSurfaceImage.clear(); m_platformSurfaceImage = 0; this->canvas()->drawingContext()->setState(m_savedState); #endif #if ENABLE(DASHBOARD_SUPPORT) clearPathForDashboardBackwardCompatibilityMode(); #endif }
Tim Horton
Comment 10 2013-07-12 00:47:11 PDT
(In reply to comment #9) > 4. Copy the saved imageData to a new imageBuffer Copying the image into a new buffer seems insanely expensive for an operation like resetClip...
Rashmi Shyamasundar
Comment 11 2013-07-12 00:51:22 PDT
Yes. This approach is expensive. Thought of this as a work around, until there is any support from Core Graphics for resetClip().
Rashmi Shyamasundar
Comment 12 2013-07-12 03:38:44 PDT
Build Bot
Comment 13 2013-07-12 04:04:40 PDT
Build Bot
Comment 14 2013-07-12 04:16:22 PDT
Rik Cabanier
Comment 15 2013-07-12 10:10:05 PDT
(In reply to comment #11) > Yes. This approach is expensive. Thought of this as a work around, until there is any support from Core Graphics for resetClip(). Reading the code, it's unclear how the clip is removed. Can you explain what is happening? Will this work: ctx.clip(); ctx.save(); ctx.resetClip(); ...; // draw with no clip ctx.restore(); ...; // draw with a clip
Rashmi Shyamasundar
Comment 16 2013-07-16 06:36:08 PDT
Nope. restore() does not work for a save() that is called before the call to resetClip(). resetClip() creates a new context (graphicsContext and platformContext) which does not have any of the old saved states.
Rik Cabanier
Comment 17 2013-07-16 09:20:45 PDT
(In reply to comment #16) > Nope. restore() does not work for a save() that is called before the call to resetClip(). > > resetClip() creates a new context (graphicsContext and platformContext) which does not have any of the old saved states. That's wrong. From the spec: The resetClip() method must create a new clipping region that is the rectangle with the top left corner at (0,0) and the width and height of the coordinate space. The new clipping region replaces the current clipping region. and: Each CanvasRenderingContext2D rendering context maintains a stack of drawing states. Drawing states consist of: ... The current clipping region. So, my example should work
Build Bot
Comment 18 2013-07-17 16:14:17 PDT
Rashmi Shyamasundar
Comment 19 2013-07-22 04:24:43 PDT
The current definition of "struct State" in CanvasRenderingContext2D, does not contain any clipping region. It should probably be added, right? Please refer http://trac.webkit.org/browser/trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h .
Rik Cabanier
Comment 20 2013-07-22 22:08:04 PDT
(In reply to comment #19) > The current definition of "struct State" in CanvasRenderingContext2D, does not contain any clipping region. It should probably be added, right? Please refer http://trac.webkit.org/browser/trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h . It's hard to believe that the clip state is not tracked by save/restore. Can you prove this with a test case?
Rashmi Shyamasundar
Comment 21 2013-07-22 23:03:11 PDT
Consider the below scenario - ctx.save(); ctx.clip(); ...; // draw with clip ctx.restore(); ...; // draw without a clip Any scenario like the above will work because when "ctx->save()" or "ctx->restore" is called, it will call save() or restore() on the GraphicsContext which in turn will call "restorePlatformState()" which in turn calls CGContextRestoreGState() or cairo_restore() for CG and Cairo respectively. In CG/Cairo, clipping-region is part of the context state. In other words, the platformContext-state consists of the clipping region unlike GraphicsContextState and CanvasrenderingContext2D-state.
Rashmi Shyamasundar
Comment 22 2013-08-11 23:14:11 PDT
Can the cairo-implementation of the API resetClip(), be committed to WebKit? The corresponding CG implementation might take time.
Dean Jackson
Comment 23 2013-08-12 12:49:01 PDT
(In reply to comment #22) > Can the cairo-implementation of the API resetClip(), be committed to WebKit? > The corresponding CG implementation might take time. Yes.
Simon Fraser (smfr)
Comment 24 2013-10-08 16:55:32 PDT
I don't think WebKit should support resetClip().
Rashmi Shyamasundar
Comment 25 2013-10-29 05:12:48 PDT
As discussed with Mr. Simon Fraser :- The reason resetClip() is a bad API is that it breaks the ability to robustly modularize drawing code. For example, say that you have the following code: context.save(); // … set up a path to clip to context.clip(); someJSLibrary.drawSomething(); context.restore(); In the absence of resetClip(), you are guaranteed that someJSLibrary.drawSomething() can’t draw outside of the clip you specified. With resetClip(), that JS library can draw wherever the heck it wants, which may totally break your canvas drawing. If you really need resetClip() in your own drawing code, you’re probably doing it wrong.
Ian 'Hixie' Hickson
Comment 26 2013-11-06 19:40:49 PST
Wouldn't that apply to resetTransform() also?
Dirk Schulze
Comment 27 2013-11-06 21:35:24 PST
(In reply to comment #26) > Wouldn't that apply to resetTransform() also? Implementation wise no. As written in the spec today, it is the same as setTransform(1,0,0,1,0,0) and implementations can easily recover.
Dean Jackson
Comment 28 2014-09-12 16:48:37 PDT
We're not going to do this for the reasons stated above.
Note You need to log in before you can comment on or make changes to this bug.