Skip to content

Commit

Permalink
Support using an externally manage list of images in UrlDataManager f…
Browse files Browse the repository at this point in the history
…or wasm debugger.

Bug: skia:9746
Change-Id: I07b5fe1f8f4250e29153b71ce2be106461f09928
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/261998
Commit-Queue: Nathaniel Nifong <[email protected]>
Reviewed-by: Kevin Lubick <[email protected]>
  • Loading branch information
Nathaniel Nifong authored and Skia Commit-Bot committed Jan 3, 2020
1 parent 365c366 commit a14d809
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 38 deletions.
22 changes: 8 additions & 14 deletions experimental/wasm-skp-debugger/debugger_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,14 @@ struct SimpleImageInfo {
int height;
SkColorType colorType;
SkAlphaType alphaType;
// Shown in the textual description of the image, and used as a common identifier between
// the resources tab and the command list.
// TODO(nifong) make the command list use the resource tab's ids instead of UrlDataManager
uintptr_t imageAddress;
};

SkImageInfo toSkImageInfo(const SimpleImageInfo& sii) {
return SkImageInfo::Make(sii.width, sii.height, sii.colorType, sii.alphaType);
}

SimpleImageInfo toSimpleImageInfo(const SkImageInfo& ii, const SkImage* addr) {
return (SimpleImageInfo){ii.width(), ii.height(), ii.colorType(), ii.alphaType(), (uintptr_t)addr};
SimpleImageInfo toSimpleImageInfo(const SkImageInfo& ii) {
return (SimpleImageInfo){ii.width(), ii.height(), ii.colorType(), ii.alphaType()};
}

class SkpDebugPlayer {
Expand Down Expand Up @@ -242,7 +238,7 @@ class SkpDebugPlayer {

// Get the image info of one of the resource images.
SimpleImageInfo getImageInfo(int index) {
return toSimpleImageInfo(fImages[index]->imageInfo(), fImages[index].get());
return toSimpleImageInfo(fImages[index]->imageInfo());
}

// return a list of layer draw events that happened at the beginning of this frame.
Expand Down Expand Up @@ -323,6 +319,8 @@ class SkpDebugPlayer {
i++;
}
fImages = deserialContext->fImages;

udm.indexImages(fImages);
}

// constrains the draw command index to the frame's command list length.
Expand All @@ -349,11 +347,8 @@ class SkpDebugPlayer {

// The URLDataManager here is a cache that accepts encoded data (pngs) and puts
// numbers on them. We have our own collection of images (fImages) that was populated by the
// SkSharingDeserialContext when mskp files are loaded. It would be nice to have the mapping
// indices between these two caches so the urls displayed in command info match the list
// in the resource tab, and to make cross linking possible. One way to do this would be to
// look up all of fImages in udm but the exact encoding of the PNG differs and we wouldn't
// find anything. TODO(nifong): Unify these two numbering schemes in CollatingCanvas.
// SkSharingDeserialContext when mskp files are loaded which it can use for IDing images
// without having to serialize them.
UrlDataManager udm;

// A structure holding the picture information needed to draw any layers used in an mskp file
Expand Down Expand Up @@ -481,8 +476,7 @@ EMSCRIPTEN_BINDINGS(my_module) {
.field("width", &SimpleImageInfo::width)
.field("height", &SimpleImageInfo::height)
.field("colorType", &SimpleImageInfo::colorType)
.field("alphaType", &SimpleImageInfo::alphaType)
.field("imageAddress", &SimpleImageInfo::imageAddress);
.field("alphaType", &SimpleImageInfo::alphaType);
constant("TRANSPARENT", (JSColor) SK_ColorTRANSPARENT);
function("_getRasterDirectSurface", optional_override([](const SimpleImageInfo ii,
uintptr_t /* uint8_t* */ pPtr,
Expand Down
20 changes: 20 additions & 0 deletions tools/UrlDataManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "tools/UrlDataManager.h"

#include <unordered_map>

bool operator==(const SkData& a, const SkData& b) {
return a.equals(&b);
}
Expand Down Expand Up @@ -42,3 +44,21 @@ void UrlDataManager::reset() {

fCache.rewind();
}

void UrlDataManager::indexImages(const std::vector<sk_sp<SkImage>>& images) {
SkASSERT(imageMap.size() == 0); // this method meant only for initialization once.
for (size_t i = 0; i < images.size(); ++i) {
imageMap.insert({images[i].get(), i});
}
}

int UrlDataManager::lookupImage(const SkImage* im) {
auto search = imageMap.find(im);
if (search != imageMap.end()) {
return search->second;
} else {
// -1 signals the pointer to this image wasn't in the original list.
// Maybe it was synthesized after file load? If so, you shouldn't be looking it up here.
return -1;
}
}
25 changes: 25 additions & 0 deletions tools/UrlDataManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
#define SkUrlDataManager_DEFINED

#include "include/core/SkData.h"
#include "include/core/SkImage.h"
#include "include/core/SkString.h"
#include "src/core/SkOpts.h"
#include "src/core/SkTDynamicHash.h"

#include <unordered_map>

/*
* A simple class which allows clients to add opaque data types, and returns a url where this data
* will be hosted. Its up to the owner of this class to actually serve the data.
Expand Down Expand Up @@ -44,6 +47,27 @@ class UrlDataManager {
}
void reset();

// Methods used to identify images differently in wasm debugger for mskp animations.
// serving is uncessary, as a collection of images with identifiers is already present, we
// just want to use it when serializing commands.

/*
* Construct an index from a list of images
* (expected to be the list that was loaded from the mskp file)
* Use only once.
*/
void indexImages(const std::vector<sk_sp<SkImage>>&);

/*
* Reports whether this UDM has an initialized image index (effevitely whether we're in wasm)
*/
bool hasImageIndex() { return imageMap.size() > 0; }

/*
* Return the file id (index of the image in the originally provided list) of an SkImage
*/
int lookupImage(const SkImage*);

private:
struct LookupTrait {
// We use the data as a hash, this is not really optimal but is fine until proven otherwise
Expand Down Expand Up @@ -71,6 +95,7 @@ class UrlDataManager {
SkTDynamicHash<UrlData, SkData, LookupTrait> fCache;
SkTDynamicHash<UrlData, SkString, ReverseLookupTrait> fUrlLookup;
uint32_t fDataId;
std::unordered_map<const SkImage*, int> imageMap;
};

#endif
58 changes: 34 additions & 24 deletions tools/debugger/DrawCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
#define DEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
#define DEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
#define DEBUGCANVAS_ATTRIBUTE_IMAGE "image"
#define DEBUGCANVAS_ATTRIBUTE_IMAGE_ADDRESS "imageAddress"
#define DEBUGCANVAS_ATTRIBUTE_IMAGE_INDEX "imageIndex"
#define DEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
#define DEBUGCANVAS_ATTRIBUTE_SRC "src"
#define DEBUGCANVAS_ATTRIBUTE_DST "dst"
Expand Down Expand Up @@ -1318,12 +1318,16 @@ bool DrawImageCommand::render(SkCanvas* canvas) const {

void DrawImageCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
INHERITED::toJSON(writer, urlDataManager);
writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
flatten(*fImage, writer, urlDataManager);
writer.endObject(); // image

writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_ADDRESS);
writer.appendU64((uint64_t)fImage.get());

if (urlDataManager.hasImageIndex()) {
writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_INDEX);
writer.appendU64((uint64_t)urlDataManager.lookupImage(fImage.get()));
} else {
writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
flatten(*fImage, writer, urlDataManager);
writer.endObject(); // image
}

writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
MakeJsonPoint(writer, fLeft, fTop);
Expand Down Expand Up @@ -1377,12 +1381,14 @@ bool DrawImageLatticeCommand::render(SkCanvas* canvas) const {

void DrawImageLatticeCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
INHERITED::toJSON(writer, urlDataManager);
writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
flatten(*fImage, writer, urlDataManager);
writer.endObject(); // image

writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_ADDRESS);
writer.appendU64((uint64_t)fImage.get());
if (urlDataManager.hasImageIndex()) {
writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_INDEX);
writer.appendU64((uint64_t)urlDataManager.lookupImage(fImage.get()));
} else {
writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
flatten(*fImage, writer, urlDataManager);
writer.endObject(); // image
}

writer.appendName(DEBUGCANVAS_ATTRIBUTE_LATTICE);
MakeJsonLattice(writer, fLattice);
Expand Down Expand Up @@ -1426,12 +1432,14 @@ bool DrawImageRectCommand::render(SkCanvas* canvas) const {

void DrawImageRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
INHERITED::toJSON(writer, urlDataManager);
writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
flatten(*fImage, writer, urlDataManager);
writer.endObject(); // image

writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_ADDRESS);
writer.appendU64((uint64_t)fImage.get());
if (urlDataManager.hasImageIndex()) {
writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_INDEX);
writer.appendU64((uint64_t)urlDataManager.lookupImage(fImage.get()));
} else {
writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
flatten(*fImage, writer, urlDataManager);
writer.endObject(); // image
}

if (fSrc.isValid()) {
writer.appendName(DEBUGCANVAS_ATTRIBUTE_SRC);
Expand Down Expand Up @@ -1536,12 +1544,14 @@ bool DrawImageNineCommand::render(SkCanvas* canvas) const {

void DrawImageNineCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
INHERITED::toJSON(writer, urlDataManager);
writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
flatten(*fImage, writer, urlDataManager);
writer.endObject(); // image

writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_ADDRESS);
writer.appendU64((uint64_t)fImage.get());
if (urlDataManager.hasImageIndex()) {
writer.appendName(DEBUGCANVAS_ATTRIBUTE_IMAGE_INDEX);
writer.appendU64((uint64_t)urlDataManager.lookupImage(fImage.get()));
} else {
writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
flatten(*fImage, writer, urlDataManager);
writer.endObject(); // image
}

writer.appendName(DEBUGCANVAS_ATTRIBUTE_CENTER);
MakeJsonIRect(writer, fCenter);
Expand Down

0 comments on commit a14d809

Please sign in to comment.