35#include <emscripten.h>
36#include <emscripten/bind.h>
46#include <emscripten/html5.h>
53static constexpr char kMultiMagic[] =
"Skia Multi-Picture Doc\n\n";
72 SkDebugf(
"Could not decode an image\n");
77 SkDebugf(
"Could not make an image from a codec\n");
102 const uint8_t*
data =
reinterpret_cast<const uint8_t*
>(cptr);
110 SkDebugf(
"Try reading as a multi-frame skp\n");
114 SkDebugf(
"Try reading as single-frame skp\n");
116 std::unique_ptr<DebugCanvas> canvas = loadSingleFrame(&
stream);
118 return "Error loading single frame";
120 frames.push_back(std::move(canvas));
130 if (fInspectedLayer >= 0) {
131 fLayerManager->setCommand(fInspectedLayer, fp, index);
133 index = constrainFrameCommand(index);
136 auto* canvas =
surface->getCanvas();
138 if (fInspectedLayer >= 0) {
140 fLayerManager->drawLayerEventTo(
surface, fInspectedLayer, fp);
143 frames[fp]->drawTo(
surface->getCanvas(), index);
145#ifdef CK_ENABLE_WEBGL
152 auto* canvas =
surface->getCanvas();
154 frames[fp]->draw(
surface->getCanvas());
155#ifdef CK_ENABLE_WEBGL
163 if (fInspectedLayer < 0) {
164 return fBoundsArray[
frame];
166 auto summary = fLayerManager->event(fInspectedLayer, fp);
178 if (fInspectedLayer >=0) {
179 return fLayerManager->getEventDebugCanvas(fInspectedLayer, fp);
181 return frames[fp].get();
190 for (
size_t i=0;
i < frames.size();
i++) {
191 frames[
i]->setOverdrawViz(on);
193 fLayerManager->setOverdrawViz(on);
196 for (
size_t i=0;
i < frames.size();
i++) {
197 frames[
i]->setDrawGpuOpBounds(on);
199 fLayerManager->setDrawGpuOpBounds(on);
202 for (
size_t i=0;
i < frames.size();
i++) {
208 for (
size_t i=0;
i < frames.size();
i++) {
209 frames[
i]->setAndroidClipViz(on);
214 for (
size_t i=0;
i < frames.size();
i++) {
215 frames[
i]->setOriginVisible(on);
227 if (fInspectedLayer >=0) {
228 return fLayerManager->event(fInspectedLayer, fp).commandCount;
230 return frames[fp]->getSize();
234 return frames.size();
245 auto skdata =
stream.detachAsData();
247 std::string_view data_view(
reinterpret_cast<const char*
>(skdata->data()), skdata->size());
249 return std::string(data_view);
268 auto skdata =
stream.detachAsData();
270 std::string_view data_view(
reinterpret_cast<const char*
>(skdata->data()), skdata->size());
272 return std::string(data_view);
289 dst.prepend(
"data:image/png;base64,");
290 return std::string(
dst.c_str());
294 return fImages.size();
308 DebugCanvas* debugCanvas = frames[framenumber].get();
310 debugCanvas = fLayerManager->getEventDebugCanvas(nodeid, framenumber);
313 for (
auto it =
map.begin(); it !=
map.end(); ++it) {
314 JSArray list = emscripten::val::array();
315 for (
const int commandId : it->second) {
316 list.call<
void>(
"push", commandId);
327 for (
auto summary : fLayerManager->summarizeLayers(fp)) {
328 result.call<
void>(
"push", summary);
335 for (
auto key : fLayerManager->getKeys()) {
336 JSObject item = emscripten::val::object();
337 item.set(
"frame",
key.frame);
338 item.set(
"nodeId",
key.nodeId);
339 result.call<
void>(
"push", item);
349 fInspectedLayer = nodeId;
361 int upperBound = commandIndex;
363 while (upperBound - lowerBound > 1) {
364 int command = (upperBound - lowerBound) / 2 + lowerBound;
366 if (c == finalColor) {
400 SkDebugf(
"Unable to deserialze frame.\n");
406 std::unique_ptr<DebugCanvas> debugCanvas = std::make_unique<DebugCanvas>(fBoundsArray.back());
409 debugCanvas->drawPicture(
picture);
415 auto deserialContext = std::make_unique<SkSharingDeserialContext>();
423 return "Not a MultiPictureDocument, MultiPictureDocument file version too old, or MultiPictureDocument contained 0 frames.";
427 std::vector<SkDocumentPage> pages(
page_count);
429 return "Reading frames from MultiPictureDocument failed";
432 fLayerManager = std::make_unique<DebugLayerManager>();
435 for (
const auto&
page : pages) {
437 fBoundsArray.push_back(
page.fPicture->cullRect().roundOut());
438 std::unique_ptr<DebugCanvas> debugCanvas = std::make_unique<DebugCanvas>(fBoundsArray.back());
439 debugCanvas->setLayerManagerAndFrame(fLayerManager.get(),
i);
442 debugCanvas->drawPicture(
page.fPicture);
444 if (debugCanvas->getSize() <=0 ){
445 SkDebugf(
"Skipped corrupted frame, had %d commands \n", debugCanvas->getSize());
449 debugCanvas->setOverdrawViz(
false);
450 debugCanvas->setDrawGpuOpBounds(
false);
452 debugCanvas->setAndroidClipViz(
false);
453 frames.push_back(std::move(debugCanvas));
456 fImages = deserialContext->fImages;
463 int constrainFrameCommand(
int index) {
464 int cmdlen = frames[fp]->getSize();
465 if (index >= cmdlen) {
472 std::vector<std::unique_ptr<DebugCanvas>> frames;
477 std::vector<SkIRect> fBoundsArray;
479 std::vector<sk_sp<SkImage>> fImages;
490 std::unique_ptr<DebugLayerManager> fLayerManager;
495 int fInspectedLayer = -1;
504 class_<SkpDebugPlayer>(
"SkpDebugPlayer")
538 value_object<SkIRect>(
"SkIRect")
545 register_vector<DebugLayerManager::LayerSummary>(
"VectorLayerSummary");
546 value_object<DebugLayerManager::LayerSummary>(
"LayerSummary")
553 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)
std::unique_ptr< SkCodec > DecodeImageData(sk_sp< SkData > data)
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 &)
const void * data() const
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)
static sk_sp< SkImage > deserializeImage(sk_sp< SkData > data, std::optional< SkAlphaType >, void *)
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
const myers::Point & get< 0 >(const myers::Segment &s)
const myers::Point & get(const myers::Segment &)
SK_API GrSemaphoresSubmitted Flush(sk_sp< SkSurface >)
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
static SkString to_string(int n)
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
SkDeserialImageFromDataProc fImageDataProc
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)
std::shared_ptr< const fml::Mapping > data