33#include <emscripten.h>
34#include <emscripten/bind.h>
44#include <emscripten/html5.h>
51static constexpr char kMultiMagic[] =
"Skia Multi-Picture Doc\n\n";
86 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(cptr);
94 SkDebugf(
"Try reading as a multi-frame skp\n");
95 const auto&
error = loadMultiFrame(&stream);
98 SkDebugf(
"Try reading as single-frame skp\n");
100 std::unique_ptr<DebugCanvas> canvas = loadSingleFrame(&stream);
102 return "Error loading single frame";
104 frames.push_back(std::move(canvas));
114 if (fInspectedLayer >= 0) {
115 fLayerManager->setCommand(fInspectedLayer, fp, index);
117 index = constrainFrameCommand(index);
120 auto* canvas =
surface->getCanvas();
122 if (fInspectedLayer >= 0) {
124 fLayerManager->drawLayerEventTo(
surface, fInspectedLayer, fp);
127 frames[fp]->drawTo(
surface->getCanvas(), index);
129#ifdef CK_ENABLE_WEBGL
136 auto* canvas =
surface->getCanvas();
138 frames[fp]->draw(
surface->getCanvas());
139#ifdef CK_ENABLE_WEBGL
147 if (fInspectedLayer < 0) {
148 return fBoundsArray[
frame];
150 auto summary = fLayerManager->event(fInspectedLayer, fp);
162 if (fInspectedLayer >=0) {
163 return fLayerManager->getEventDebugCanvas(fInspectedLayer, fp);
165 return frames[fp].get();
174 for (
size_t i=0; i < frames.size(); i++) {
175 frames[i]->setOverdrawViz(on);
177 fLayerManager->setOverdrawViz(on);
180 for (
size_t i=0; i < frames.size(); i++) {
181 frames[i]->setDrawGpuOpBounds(on);
183 fLayerManager->setDrawGpuOpBounds(on);
186 for (
size_t i=0; i < frames.size(); i++) {
192 for (
size_t i=0; i < frames.size(); i++) {
193 frames[i]->setAndroidClipViz(on);
198 for (
size_t i=0; i < frames.size(); i++) {
199 frames[i]->setOriginVisible(on);
211 if (fInspectedLayer >=0) {
212 return fLayerManager->event(fInspectedLayer, fp).commandCount;
214 return frames[fp]->getSize();
218 return frames.size();
229 auto skdata = stream.detachAsData();
231 std::string_view data_view(
reinterpret_cast<const char*
>(skdata->data()), skdata->size());
233 return std::string(data_view);
252 auto skdata = stream.detachAsData();
254 std::string_view data_view(
reinterpret_cast<const char*
>(skdata->data()), skdata->size());
256 return std::string(data_view);
273 dst.prepend(
"data:image/png;base64,");
274 return std::string(dst.c_str());
278 return fImages.size();
292 DebugCanvas* debugCanvas = frames[framenumber].get();
294 debugCanvas = fLayerManager->getEventDebugCanvas(nodeid, framenumber);
297 for (
auto it = map.begin(); it != map.end(); ++it) {
298 JSArray list = emscripten::val::array();
299 for (
const int commandId : it->second) {
300 list.call<
void>(
"push", commandId);
302 result.set(std::to_string(it->first), list);
311 for (
auto summary : fLayerManager->summarizeLayers(fp)) {
312 result.call<
void>(
"push", summary);
319 for (
auto key : fLayerManager->getKeys()) {
320 JSObject item = emscripten::val::object();
321 item.set(
"frame",
key.frame);
322 item.set(
"nodeId",
key.nodeId);
323 result.call<
void>(
"push", item);
333 fInspectedLayer = nodeId;
345 int upperBound = commandIndex;
347 while (upperBound - lowerBound > 1) {
348 int command = (upperBound - lowerBound) / 2 + lowerBound;
349 auto c = evaluateCommandColor(
surface, command,
x,
y);
350 if (c == finalColor) {
351 upperBound = command;
353 lowerBound = command;
378 std::unique_ptr<DebugCanvas> loadSingleFrame(
SkMemoryStream* stream) {
382 SkDebugf(
"Unable to deserialze frame.\n");
388 std::unique_ptr<DebugCanvas> debugCanvas = std::make_unique<DebugCanvas>(fBoundsArray.back());
391 debugCanvas->drawPicture(picture);
397 auto deserialContext = std::make_unique<SkSharingDeserialContext>();
405 return "Not a MultiPictureDocument, MultiPictureDocument file version too old, or MultiPictureDocument contained 0 frames.";
407 SkDebugf(
"Expecting %d frames\n", page_count);
409 std::vector<SkDocumentPage> pages(page_count);
411 return "Reading frames from MultiPictureDocument failed";
414 fLayerManager = std::make_unique<DebugLayerManager>();
417 for (
const auto& page : pages) {
419 fBoundsArray.push_back(
page.fPicture->cullRect().roundOut());
420 std::unique_ptr<DebugCanvas> debugCanvas = std::make_unique<DebugCanvas>(fBoundsArray.back());
421 debugCanvas->setLayerManagerAndFrame(fLayerManager.get(), i);
424 debugCanvas->drawPicture(
page.fPicture);
426 if (debugCanvas->getSize() <=0 ){
427 SkDebugf(
"Skipped corrupted frame, had %d commands \n", debugCanvas->getSize());
431 debugCanvas->setOverdrawViz(
false);
432 debugCanvas->setDrawGpuOpBounds(
false);
434 debugCanvas->setAndroidClipViz(
false);
435 frames.push_back(std::move(debugCanvas));
438 fImages = deserialContext->fImages;
445 int constrainFrameCommand(
int index) {
446 int cmdlen = frames[fp]->getSize();
447 if (index >= cmdlen) {
454 std::vector<std::unique_ptr<DebugCanvas>> frames;
459 std::vector<SkIRect> fBoundsArray;
461 std::vector<sk_sp<SkImage>> fImages;
472 std::unique_ptr<DebugLayerManager> fLayerManager;
477 int fInspectedLayer = -1;
486 class_<SkpDebugPlayer>(
"SkpDebugPlayer")
520 value_object<SkIRect>(
"SkIRect")
527 register_vector<DebugLayerManager::LayerSummary>(
"VectorLayerSummary");
528 value_object<DebugLayerManager::LayerSummary>(
"LayerSummary")
535 value_object<ImageInfoNoColorspace>(
"ImageInfoNoColorspace")
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kOpaque_SkAlphaType
pixel is opaque
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
constexpr SkColor SK_ColorTRANSPARENT
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
const SkIRect & getCurrentClip()
std::map< int, std::vector< int > > getImageIdToCommandMap(UrlDataManager &udm) const
const SkM44 & getCurrentMatrix()
void toggleCommand(int index, bool toggle)
void toJSON(SkJSONWriter &writer, UrlDataManager &urlDataManager, SkCanvas *)
void deleteDrawCommandAt(int index)
static void MakeJsonMatrix44(SkJSONWriter &, const SkM44 &)
static void MakeJsonIRect(SkJSONWriter &, const SkIRect &)
void beginObject(const char *name=nullptr, bool multiline=true)
void appendName(const char *name)
virtual SkRect cullRect() const =0
static sk_sp< SkPicture > MakeFromStream(SkStream *stream, const SkDeserialProcs *procs=nullptr)
std::string jsonCommandList(sk_sp< SkSurface > surface)
void setCommandVisibility(int index, bool visible)
int findCommandByPixel(SkSurface *surface, int x, int y, int commandIndex)
std::string getImageResource(int index)
void setAndroidClipViz(bool on)
void setOriginVisible(bool on)
JSObject imageUseInfo(int framenumber, int nodeid)
void setOverdrawVis(bool on)
std::string loadSkp(uintptr_t cptr, int length)
void draw(SkSurface *surface)
void changeFrame(int index)
const SkIRect getBoundsForFrame(int32_t frame)
JSArray getLayerSummariesJs()
void drawTo(SkSurface *surface, int32_t index)
void deleteCommand(int index)
DebugCanvas * visibleCanvas()
void setClipVizColor(JSColor color)
void setGpuOpBounds(bool on)
const SkIRect getBounds()
std::string lastCommandInfo()
int getFrameCount() const
void setInspectedLayer(int nodeId)
ImageInfoNoColorspace getImageInfo(int index)
void indexImages(const std::vector< sk_sp< SkImage > > &)
ImageInfoNoColorspace toImageInfoNoColorspace(const SkImageInfo &ii)
EMSCRIPTEN_BINDINGS(my_module)
static constexpr char kMultiMagic[]
const uint8_t uint32_t uint32_t GError ** error
Dart_NativeFunction function
SK_API bool Read(SkStreamSeekable *src, SkDocumentPage *dstArray, int dstArrayCount, const SkDeserialProcs *=nullptr)
SK_API int ReadPageCount(SkStreamSeekable *src)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
sk_sp< const SkPicture > picture
SK_API GrSemaphoresSubmitted Flush(sk_sp< SkSurface >)
static size_t EncodedSize(size_t srcDataLength)
static size_t Encode(const void *src, size_t length, void *dst, const char *encode=nullptr)
SkDeserialImageProc fImageProc
int32_t fBottom
larger y-axis bounds
int32_t fTop
smaller y-axis bounds
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
int32_t fLeft
smaller x-axis bounds
int32_t fRight
larger x-axis bounds
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkAlphaType alphaType() const
SkColorType colorType() const
void roundOut(SkIRect *dst) const
static sk_sp< SkImage > deserializeImage(const void *data, size_t length, void *ctx)