Skip to content

Commit

Permalink
Bug 7691406: Fix animation related crashes related to RenderAsync
Browse files Browse the repository at this point in the history
This change fixes crash in WinRT RenderAsync when an invalid Layer
is passed to it. Though the API was doing the same before, PPL
task chaining change for the fiber-less UI exposed this issue as
the exception now gets propogated through the chain.

Fixes #517
  • Loading branch information
mnithish authored and Raj Seshasankaran committed May 31, 2016
1 parent c68bc7f commit 17cf90a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 13 deletions.
25 changes: 19 additions & 6 deletions Frameworks/UIKit/StarboardXaml/CALayerXaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "LoggingNative.h"
#include "CALayerXaml.h"
#include <StringHelpers.h>
#include <LoggingNative.h>
#include <algorithm>

using namespace concurrency;
Expand All @@ -42,6 +43,8 @@ using namespace Windows::UI::Xaml::Media::Imaging;
using namespace Windows::UI::Xaml::Shapes;
using namespace Windows::Graphics::Display;

static const wchar_t* TAG = L"CALayerXaml";

namespace XamlCompositor {
namespace Controls {
//
Expand Down Expand Up @@ -1438,7 +1441,7 @@ void CALayerXaml::SetTopMost() {
__super::Background = nullptr;
}

void CALayerXaml::setContentImage(ImageSource^ source, float width, float height, float scale) {
void CALayerXaml::SetContentImage(ImageSource^ source, float width, float height, float scale) {
if (source == nullptr) {
if (Util::isInstanceOf<LayerContent^>(m_content)) {
_SetContent(nullptr);
Expand All @@ -1451,7 +1454,7 @@ void CALayerXaml::setContentImage(ImageSource^ source, float width, float height
}
}

void CALayerXaml::setContentElement(FrameworkElement^ elem, float width, float height, float scale) {
void CALayerXaml::SetContentElement(FrameworkElement^ elem, float width, float height, float scale) {
if (elem == nullptr) {
if (Util::isInstanceOf<LayerContent^>(m_content)) {
_SetContent(nullptr);
Expand Down Expand Up @@ -1694,18 +1697,28 @@ concurrency::task<CALayerXaml^> EventedStoryboard::SnapshotLayer(CALayerXaml^ la
}
else {
RenderTargetBitmap^ snapshot = ref new RenderTargetBitmap();

return concurrency::create_task(snapshot->RenderAsync(layer, (int)(layer->CurrentWidth * CALayerXaml::s_screenScale), 0))
.then([snapshot, layer](concurrency::task<void> result) {
.then([snapshot, layer](concurrency::task<void> result) noexcept {
try {
result.get();
} catch (Platform::InvalidArgumentException^ ex) {
// Handle exceptions related to invalid layer attribute passed to RenderAsync
TraceWarning(TAG,
L"RenderAsync threw InvalidArgumentException exception - [%ld]%s",
ex->HResult,
ex->Message);
return (CALayerXaml^)nullptr;
}

// Return a new 'copy' layer with the rendered content
CALayerXaml^ newLayer = CALayerXaml::CreateLayer();
newLayer->_CopyPropertiesFrom(layer);

int width = snapshot->PixelWidth;
int height = snapshot->PixelHeight;
DisplayInformation^ dispInfo = Windows::Graphics::Display::DisplayInformation::GetForCurrentView();

newLayer->setContentImage(snapshot, (float)width, (float)height, (float)(CALayerXaml::s_screenScale * dispInfo->RawPixelsPerViewPixel));
newLayer->SetContentImage(snapshot, (float)width, (float)height, (float)(CALayerXaml::s_screenScale * dispInfo->RawPixelsPerViewPixel));

// There seems to be a bug in Xaml where Render'd layers get sized to their visible content... sort of.
// If the UIViewController being transitioned away from has transparent content, the height returned is less the
Expand Down
4 changes: 2 additions & 2 deletions Frameworks/UIKit/StarboardXaml/CALayerXaml.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ public ref class CALayerXaml sealed : Windows::UI::Xaml::Controls::Panel, ICache
void SetupBackground();
void SetBackgroundColor(float r, float g, float b, float a);
void SetTopMost();
void setContentImage(Windows::UI::Xaml::Media::ImageSource^ source, float width, float height, float scale);
void setContentElement(Windows::UI::Xaml::FrameworkElement^ elem, float width, float height, float scale);
void SetContentImage(Windows::UI::Xaml::Media::ImageSource^ source, float width, float height, float scale);
void SetContentElement(Windows::UI::Xaml::FrameworkElement^ elem, float width, float height, float scale);

protected:
// Windows::UI::Xaml::Automation::Peers::AutomationPeer^ OnCreateAutomationPeer() override;
Expand Down
10 changes: 5 additions & 5 deletions Frameworks/UIKit/StarboardXaml/XamlCompositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ concurrency::task<void> DisplayAnimation::AddTransitionAnimation(DisplayNode* no

// Render a layer snapshot, then kick off the animation
return xamlAnimation->SnapshotLayer(xamlNode)
.then([this, xamlAnimation, xamlNode, wtype, wsubtype](XamlCompositor::Controls::CALayerXaml^ snapshotLayer) {
.then([this, xamlAnimation, xamlNode, wtype, wsubtype](XamlCompositor::Controls::CALayerXaml^ snapshotLayer) noexcept {

xamlAnimation->AddTransition(
xamlNode,
Expand Down Expand Up @@ -513,16 +513,16 @@ void DisplayNode::SetContents(winobjc::Id& bitmap, float width, float height, fl
XamlCompositor::Controls::CALayerXaml^ xamlNode = GetCALayer(this);
if (((void*)bitmap) != NULL) {
auto contents = (Windows::UI::Xaml::Media::ImageSource^)(Platform::Object^)bitmap;
xamlNode->setContentImage(contents, width, height, scale);
xamlNode->SetContentImage(contents, width, height, scale);
} else {
xamlNode->setContentImage(nullptr, width, height, scale);
xamlNode->SetContentImage(nullptr, width, height, scale);
}
}

void DisplayNode::SetContentsElement(winobjc::Id& elem, float width, float height, float scale) {
XamlCompositor::Controls::CALayerXaml^ xamlNode = GetCALayer(this);
Windows::UI::Xaml::FrameworkElement^ contents = (Windows::UI::Xaml::FrameworkElement^)(Platform::Object^)elem;
xamlNode->setContentElement(contents, width, height, scale);
xamlNode->SetContentElement(contents, width, height, scale);
}

void DisplayNode::SetContentsElement(winobjc::Id& elem) {
Expand All @@ -531,7 +531,7 @@ void DisplayNode::SetContentsElement(winobjc::Id& elem) {
float width = static_cast<float>(contents->Width);
float height = static_cast<float>(contents->Height);
float scale = 1.0f;
xamlNode->setContentElement(contents, width, height, scale);
xamlNode->SetContentElement(contents, width, height, scale);
}

DisplayTextureXamlGlyphs::DisplayTextureXamlGlyphs() {
Expand Down

0 comments on commit 17cf90a

Please sign in to comment.