1313#include " tools/SkSharingProc.h"
1414#include " tools/UrlDataManager.h"
1515#include " tools/debugger/DebugCanvas.h"
16+ #include " tools/debugger/DebugLayerManager.h"
1617
18+ #include < memory>
19+ #include < string>
20+ #include < string_view>
21+ #include < vector>
1722#include < emscripten.h>
1823#include < emscripten/bind.h>
1924
@@ -98,10 +103,20 @@ class SkpDebugPlayer {
98103 SkDebugf (" Constrained command index (%d) within this frame's length (%d)\n " , index, cmdlen);
99104 index = cmdlen-1 ;
100105 }
106+ auto * canvas = surface->getCanvas ();
107+ canvas->clear (SK_ColorTRANSPARENT);
101108 frames[fp]->drawTo (surface->getCanvas (), index);
102109 surface->getCanvas ()->flush ();
103110 }
104111
112+ // Draws to the end of the current frame.
113+ void draw (SkSurface* surface) {
114+ auto * canvas = surface->getCanvas ();
115+ canvas->clear (SK_ColorTRANSPARENT);
116+ frames[fp]->draw (surface->getCanvas ());
117+ surface->getCanvas ()->flush ();
118+ }
119+
105120 const SkIRect& getBounds () { return fBounds ; }
106121
107122 // The following three operations apply to every frame because they are overdraw features.
@@ -201,6 +216,11 @@ class SkpDebugPlayer {
201216 return toSimpleImageInfo (fImages [index]->imageInfo (), fImages [index].get ());
202217 }
203218
219+ // return a list of layer draw events that happened at the beginning of this frame.
220+ std::vector<DebugLayerManager::DrawEventSummary> getLayerDrawEvents () {
221+ return fLayerManager ->summarizeEvents (fp);
222+ }
223+
204224 private:
205225
206226 // Loads a single frame (traditional) skp file from the provided data stream and returns
@@ -215,54 +235,57 @@ class SkpDebugPlayer {
215235 SkDebugf (" Parsed SKP file.\n " );
216236 // Make debug canvas using bounds from SkPicture
217237 fBounds = picture->cullRect ().roundOut ();
218- std::unique_ptr<DebugCanvas> debugDanvas = std::make_unique<DebugCanvas>(fBounds );
219- SkDebugf (" DebugCanvas created.\n " );
238+ std::unique_ptr<DebugCanvas> debugCanvas = std::make_unique<DebugCanvas>(fBounds );
220239
221240 // Only draw picture to the debug canvas once.
222- debugDanvas->drawPicture (picture);
223- SkDebugf (" Added picture with %d commands.\n " , debugDanvas->getSize ());
224- return debugDanvas;
241+ debugCanvas->drawPicture (picture);
242+ return debugCanvas;
225243 }
226244
227245 void loadMultiFrame (SkMemoryStream* stream) {
246+ // Attempt to deserialize with an image sharing serial proc.
247+ auto deserialContext = std::make_unique<SkSharingDeserialContext>();
248+ SkDeserialProcs procs;
249+ procs.fImageProc = SkSharingDeserialContext::deserializeImage;
250+ procs.fImageCtx = deserialContext.get ();
251+
252+ int page_count = SkMultiPictureDocumentReadPageCount (stream);
253+ if (!page_count) {
254+ SkDebugf (" Not a MultiPictureDocument" );
255+ return ;
256+ }
257+ SkDebugf (" Expecting %d frames\n " , page_count);
228258
229- // Attempt to deserialize with an image sharing serial proc.
230- auto deserialContext = std::make_unique<SkSharingDeserialContext>();
231- SkDeserialProcs procs ;
232- procs. fImageProc = SkSharingDeserialContext::deserializeImage ;
233- procs. fImageCtx = deserialContext. get ();
259+ std::vector<SkDocumentPage> pages (page_count);
260+ if (! SkMultiPictureDocumentRead (stream, pages. data (), page_count, &procs)) {
261+ SkDebugf ( " Reading frames from MultiPictureDocument failed " ) ;
262+ return ;
263+ }
234264
235- int page_count = SkMultiPictureDocumentReadPageCount (stream);
236- if (!page_count) {
237- SkDebugf (" Not a MultiPictureDocument" );
238- return ;
239- }
240- SkDebugf (" Expecting %d frames\n " , page_count);
265+ fLayerManager = std::make_unique<DebugLayerManager>();
241266
242- std::vector<SkDocumentPage> pages (page_count);
243- if (!SkMultiPictureDocumentRead (stream, pages.data (), page_count, &procs)) {
244- SkDebugf (" Reading frames from MultiPictureDocument failed" );
245- return ;
246- }
267+ int i = 0 ;
268+ for (const auto & page : pages) {
269+ i++;
270+ // Make debug canvas using bounds from SkPicture
271+ fBounds = page.fPicture ->cullRect ().roundOut ();
272+ std::unique_ptr<DebugCanvas> debugCanvas = std::make_unique<DebugCanvas>(fBounds );
273+ debugCanvas->setLayerManagerAndFrame (fLayerManager .get (), i);
247274
248- for (const auto & page : pages) {
249- // Make debug canvas using bounds from SkPicture
250- fBounds = page.fPicture ->cullRect ().roundOut ();
251- std::unique_ptr<DebugCanvas> debugDanvas = std::make_unique<DebugCanvas>(fBounds );
252- // Only draw picture to the debug canvas once.
253- debugDanvas->drawPicture (page.fPicture );
254- SkDebugf (" Added picture with %d commands.\n " , debugDanvas->getSize ());
255-
256- if (debugDanvas->getSize () <=0 ){
257- SkDebugf (" Skipped corrupted frame, had %d commands \n " , debugDanvas->getSize ());
258- continue ;
259- }
260- debugDanvas->setOverdrawViz (false );
261- debugDanvas->setDrawGpuOpBounds (false );
262- debugDanvas->setClipVizColor (SK_ColorTRANSPARENT);
263- frames.push_back (std::move (debugDanvas));
275+ // Only draw picture to the debug canvas once.
276+ debugCanvas->drawPicture (page.fPicture );
277+
278+ if (debugCanvas->getSize () <=0 ){
279+ SkDebugf (" Skipped corrupted frame, had %d commands \n " , debugCanvas->getSize ());
280+ continue ;
264281 }
265- fImages = deserialContext->fImages ;
282+ // If you don't set these, they're undefined.
283+ debugCanvas->setOverdrawViz (false );
284+ debugCanvas->setDrawGpuOpBounds (false );
285+ debugCanvas->setClipVizColor (SK_ColorTRANSPARENT);
286+ frames.push_back (std::move (debugCanvas));
287+ }
288+ fImages = deserialContext->fImages ;
266289 }
267290
268291 // A vector of DebugCanvas, each one initialized to a frame of the animation.
@@ -285,6 +308,10 @@ class SkpDebugPlayer {
285308 // find anything. TODO(nifong): Unify these two numbering schemes in CollatingCanvas.
286309 UrlDataManager udm;
287310
311+ // A structure holding the picture information needed to draw any layers used in an mskp file
312+ // individual frames hold a pointer to it, store draw events, and request images from it.
313+ // it is stateful and is set to the current frame at all times.
314+ std::unique_ptr<DebugLayerManager> fLayerManager ;
288315};
289316
290317#if SK_SUPPORT_GPU
@@ -356,6 +383,7 @@ EMSCRIPTEN_BINDINGS(my_module) {
356383 .constructor <>()
357384 .function (" loadSkp" , &SkpDebugPlayer::loadSkp, allow_raw_pointers ())
358385 .function (" drawTo" , &SkpDebugPlayer::drawTo, allow_raw_pointers ())
386+ .function (" draw" , &SkpDebugPlayer::draw, allow_raw_pointers ())
359387 .function (" getBounds" , &SkpDebugPlayer::getBounds)
360388 .function (" setOverdrawVis" , &SkpDebugPlayer::setOverdrawVis)
361389 .function (" setClipVizColor" , &SkpDebugPlayer::setClipVizColor)
@@ -369,14 +397,24 @@ EMSCRIPTEN_BINDINGS(my_module) {
369397 .function (" getFrameCount" , &SkpDebugPlayer::getFrameCount)
370398 .function (" getImageResource" , &SkpDebugPlayer::getImageResource)
371399 .function (" getImageCount" , &SkpDebugPlayer::getImageCount)
372- .function (" getImageInfo" , &SkpDebugPlayer::getImageInfo);
400+ .function (" getImageInfo" , &SkpDebugPlayer::getImageInfo)
401+ .function (" getLayerDrawEvents" , &SkpDebugPlayer::getLayerDrawEvents);
373402
374403 // Structs used as arguments or returns to the functions above
375404 value_object<SkIRect>(" SkIRect" )
376405 .field (" fLeft" , &SkIRect::fLeft )
377406 .field (" fTop" , &SkIRect::fTop )
378407 .field (" fRight" , &SkIRect::fRight )
379408 .field (" fBottom" , &SkIRect::fBottom );
409+ // emscripten provided the following convenience function for binding vector<T>
410+ // https://emscripten.org/docs/api_reference/bind.h.html#_CPPv415register_vectorPKc
411+ register_vector<DebugLayerManager::DrawEventSummary>(" VectorDrawEventSummary" );
412+ value_object<DebugLayerManager::DrawEventSummary>(" DebugLayerManager::DrawEventSummary" )
413+ .field (" nodeId" , &DebugLayerManager::DrawEventSummary::nodeId)
414+ .field (" fullRedraw" , &DebugLayerManager::DrawEventSummary::fullRedraw)
415+ .field (" commandCount" , &DebugLayerManager::DrawEventSummary::commandCount)
416+ .field (" layerWidth" , &DebugLayerManager::DrawEventSummary::layerWidth)
417+ .field (" layerHeight" , &DebugLayerManager::DrawEventSummary::layerHeight);
380418
381419 // Symbols needed by cpu.js to perform surface creation and flushing.
382420 enum_<SkColorType>(" ColorType" )
0 commit comments