added options to enable caching and draw bounds in NIMA slide

Bug: skia:
Change-Id: I30fed2c0587f36aeccd5e366b823a8b044a371ea
Reviewed-on: https://skia-review.googlesource.com/142164
Commit-Queue: Ruiqi Mao <ruiqimao@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
Ruiqi Mao 2018-07-20 14:18:50 -04:00 committed by Skia Commit-Bot
parent 1a9971ed47
commit 46656e298b
2 changed files with 91 additions and 62 deletions

View File

@ -56,7 +56,7 @@ public:
, fIndices() , fIndices()
, fBones() , fBones()
, fVertices(nullptr) , fVertices(nullptr)
, fRenderMode(kBackend_RenderMode) { , fRenderFlags(0) {
// Update the vertices and bones. // Update the vertices and bones.
this->updateVertices(); this->updateVertices();
this->updateBones(); this->updateBones();
@ -65,35 +65,16 @@ public:
this->updateVerticesObject(false, false); this->updateVerticesObject(false, false);
} }
void renderBackend(SkCanvas* canvas) { void render(SkCanvas* canvas, uint32_t renderFlags) {
// Reset vertices if the render mode has changed. bool dirty = renderFlags != fRenderFlags;
if (fRenderMode != kBackend_RenderMode) { fRenderFlags = renderFlags;
fRenderMode = kBackend_RenderMode;
this->updateVertices();
this->updateVerticesObject(false, false);
}
// Update the vertex data. bool useImmediate = renderFlags & kImmediate_RenderFlag;
if (fActorImage->doesAnimationVertexDeform()) { bool useCache = renderFlags & kCache_RenderFlag;
this->updateVertices(); bool drawBounds = renderFlags & kBounds_RenderFlag;
this->updateVerticesObject(false, true);
}
// Update the bones.
this->updateBones();
// Draw the vertices object.
this->drawVerticesObject(canvas, true);
}
void renderImmediate(SkCanvas* canvas) {
// Reset vertices if the render mode has changed.
if (fRenderMode != kImmediate_RenderMode) {
fRenderMode = kImmediate_RenderMode;
this->updateVertices();
this->updateVerticesObject(true, true);
}
if (useImmediate) {
// Immediate mode transforms.
// Update the vertex data. // Update the vertex data.
if (fActorImage->doesAnimationVertexDeform() && fActorImage->isVertexDeformDirty()) { if (fActorImage->doesAnimationVertexDeform() && fActorImage->isVertexDeformDirty()) {
this->updateVertices(); this->updateVertices();
@ -101,10 +82,48 @@ public:
} }
// Update the vertices object. // Update the vertices object.
this->updateVerticesObject(true, true); this->updateVerticesObject(true, true); // Immediate mode vertices change every frame,
// so they must be volatile.
} else {
// Backend transformations.
if (fActorImage->doesAnimationVertexDeform()) {
// These are vertices that transform beyond just bone transforms, so they must be
// updated every frame.
this->updateVertices();
this->updateVerticesObject(false, true);
} else if (dirty) {
// If the render flags are dirty, reset the vertices object.
this->updateVertices();
this->updateVerticesObject(false, !useCache);
}
// Update the bones.
this->updateBones();
}
// Draw the vertices object. // Draw the vertices object.
this->drawVerticesObject(canvas, false); this->drawVerticesObject(canvas, !useImmediate);
if (drawBounds && fActorImage->renderOpacity() > 0.0f) {
// Get the bounds.
SkRect bounds = fVertices->bounds();
// Approximate bounds if not using immediate transforms.
if (!useImmediate) {
const SkRect originalBounds = fBones[0].mapRect(fVertices->bounds());
bounds = originalBounds;
for (size_t i = 1; i < fBones.size(); i++) {
const SkMatrix& matrix = fBones[i];
bounds.join(matrix.mapRect(originalBounds));
}
}
// Draw the bounds.
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(0xFFFF0000);
canvas->drawRect(bounds, paint);
}
} }
int drawOrder() const { return fActorImage->drawOrder(); } int drawOrder() const { return fActorImage->drawOrder(); }
@ -316,7 +335,7 @@ private:
std::vector<SkMatrix> fBones; std::vector<SkMatrix> fBones;
sk_sp<SkVertices> fVertices; sk_sp<SkVertices> fVertices;
RenderMode fRenderMode; uint32_t fRenderFlags;
}; };
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
@ -359,21 +378,10 @@ public:
} }
} }
void render(SkCanvas* canvas, RenderMode renderMode) { void render(SkCanvas* canvas, uint32_t renderFlags) {
// Render the image nodes. // Render the image nodes.
for (auto& image : fActorImages) { for (auto& image : fActorImages) {
switch (renderMode) { image.render(canvas, renderFlags);
case kBackend_RenderMode: {
// Render with Skia backend.
image.renderBackend(canvas);
break;
}
case kImmediate_RenderMode: {
// Render with immediate backend.
image.renderImmediate(canvas);
break;
}
}
} }
} }
@ -397,7 +405,7 @@ NIMASlide::NIMASlide(const SkString& name, const SkString& path)
, fActor(nullptr) , fActor(nullptr)
, fPlaying(true) , fPlaying(true)
, fTime(0.0f) , fTime(0.0f)
, fRenderMode(kBackend_RenderMode) , fRenderFlags(0)
, fAnimation(nullptr) , fAnimation(nullptr)
, fAnimationIndex(0) { , fAnimationIndex(0) {
fName = name; fName = name;
@ -425,7 +433,7 @@ void NIMASlide::draw(SkCanvas* canvas) {
canvas->scale(0.5, -0.5); canvas->scale(0.5, -0.5);
// Render the actor. // Render the actor.
fActor->render(canvas, fRenderMode); fActor->render(canvas, fRenderFlags);
canvas->restore(); canvas->restore();
} }
@ -476,7 +484,7 @@ void NIMASlide::resetActor() {
} }
void NIMASlide::renderGUI() { void NIMASlide::renderGUI() {
ImGui::SetNextWindowSize(ImVec2(300, 220)); ImGui::SetNextWindowSize(ImVec2(300, 0));
ImGui::Begin("NIMA"); ImGui::Begin("NIMA");
// List of animations. // List of animations.
@ -506,14 +514,34 @@ void NIMASlide::renderGUI() {
ImGui::SliderFloat("Time", &fTime, 0.0f, fAnimation->max(), "Time: %.3f"); ImGui::SliderFloat("Time", &fTime, 0.0f, fAnimation->max(), "Time: %.3f");
// Backend control. // Backend control.
int renderMode = fRenderMode; int useImmediate = SkToBool(fRenderFlags & kImmediate_RenderFlag);
ImGui::Spacing(); ImGui::Spacing();
ImGui::RadioButton("Skia Backend", &renderMode, 0); ImGui::RadioButton("Skia Backend", &useImmediate, 0);
ImGui::RadioButton("Immediate Backend", &renderMode, 1); ImGui::RadioButton("Immediate Backend", &useImmediate, 1);
if (renderMode == 0) { if (useImmediate) {
fRenderMode = kBackend_RenderMode; fRenderFlags |= kImmediate_RenderFlag;
} else { } else {
fRenderMode = kImmediate_RenderMode; fRenderFlags &= ~kImmediate_RenderFlag;
}
// Cache control.
bool useCache = SkToBool(fRenderFlags & kCache_RenderFlag);
ImGui::Spacing();
ImGui::Checkbox("Cache Vertices", &useCache);
if (useCache) {
fRenderFlags |= kCache_RenderFlag;
} else {
fRenderFlags &= ~kCache_RenderFlag;
}
// Bounding box toggle.
bool drawBounds = SkToBool(fRenderFlags & kBounds_RenderFlag);
ImGui::Spacing();
ImGui::Checkbox("Draw Bounds", &drawBounds);
if (drawBounds) {
fRenderFlags |= kBounds_RenderFlag;
} else {
fRenderFlags &= ~kBounds_RenderFlag;
} }
ImGui::End(); ImGui::End();

View File

@ -20,9 +20,10 @@
class NIMAActor; class NIMAActor;
class NIMAActorImage; class NIMAActorImage;
enum RenderMode { enum RenderFlags {
kBackend_RenderMode = 0, kImmediate_RenderFlag = 0x1,
kImmediate_RenderMode = 1, kCache_RenderFlag = 0x2,
kBounds_RenderFlag = 0x4,
}; };
class NIMASlide : public Slide { class NIMASlide : public Slide {
@ -50,7 +51,7 @@ private:
bool fPlaying; bool fPlaying;
float fTime; float fTime;
RenderMode fRenderMode; uint32_t fRenderFlags;
nima::ActorAnimationInstance* fAnimation; nima::ActorAnimationInstance* fAnimation;
int fAnimationIndex; int fAnimationIndex;