From f928ec0446d8e7cabdaeb74dde65b6c9abe79ccd Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Thu, 17 Sep 2015 19:08:00 +0200 Subject: [PATCH 1/2] Enable intrinsic sizing of SWFM playback stage, based on the recorded SWF's intrinsic dimensions --- examples/swfmplayer/swfmPlayer.js | 37 +++++++++++++++++++++++++++++++ src/gfx/easel.ts | 7 +++++- src/gfx/easelHost.ts | 2 +- src/gfx/test/playbackEaselHost.ts | 29 ++++++++++++++++++++---- src/gfx/test/recorder.ts | 4 ++++ 5 files changed, 73 insertions(+), 6 deletions(-) diff --git a/examples/swfmplayer/swfmPlayer.js b/examples/swfmplayer/swfmPlayer.js index 39e85b2cc7..b5a3168367 100644 --- a/examples/swfmplayer/swfmPlayer.js +++ b/examples/swfmplayer/swfmPlayer.js @@ -37,6 +37,7 @@ var queryVariables = parseQueryString(window.location.search); var movieURL = queryVariables['swfm'] || 'tiger.swfm'; var scoreRun = queryVariables['score'] === 'true'; var fastRun = queryVariables['fast'] === 'true'; +var preview = queryVariables['preview'] === 'true'; var easelHost; function startMovie(file) { @@ -56,6 +57,42 @@ function startMovie(file) { }; } else { easel.startRendering(); + if (preview) { + easelHost.useIntrinsicSize = true; + var currentFrame = 0; + var currentPosition = 0; + var cpuTime = 0; + var previews = document.getElementById('previews'); + var frames = []; + easelHost.onFrame = function () { + var frame = document.createElement('div'); + currentFrame++; + var frameSize = easelHost.currentPosition - currentPosition; + currentPosition += frameSize; + var frameTime = easelHost.cpuTime - cpuTime; + cpuTime += frameTime; + frame.innerHTML = 'Frame ' + currentFrame + ' (size: ' + frameSize + ', render time: ' + + frameTime.toPrecision(2) + '):'; + var img = new Image(); + img.src = easel.screenShot(null, true, true).dataURL; + frame.insertBefore(img, frame.firstChild); + frames.push(frame); + }; + document.body.onscroll = function() { + if (!frames.length) { + return; + } + var currentFrame = previews.firstChild; + currentFrame && previews.removeChild(currentFrame); + previews.appendChild(frames[0]); + //if (previews.style.width === '') { + // previews.style.width = img.width + 'px'; + // previews.style.height = img.height + 'px'; + //} + "use strict"; + console.log('scr') + } + } } } diff --git a/src/gfx/easel.ts b/src/gfx/easel.ts index 25c33a84da..1048f6a1d4 100644 --- a/src/gfx/easel.ts +++ b/src/gfx/easel.ts @@ -336,7 +336,7 @@ module Shumway.GFX { this._renderer = new Canvas2D.Canvas2DRenderer(stageContainer, this._stage, this._options); this._listenForContainerSizeChanges(); - this._onMouseUp = this._onMouseUp.bind(this) + this._onMouseUp = this._onMouseUp.bind(this); this._onMouseDown = this._onMouseDown.bind(this); this._onMouseMove = this._onMouseMove.bind(this); @@ -386,6 +386,11 @@ module Shumway.GFX { }, false); } + setSize(width: number, height: number) { + this._container.style.width = width + 'px'; + this._container.style.height = height + 'px'; + } + private _listenForContainerSizeChanges() { var pollInterval = 10; var w = this._containerWidth; diff --git a/src/gfx/easelHost.ts b/src/gfx/easelHost.ts index 1658823432..37a993f1f7 100644 --- a/src/gfx/easelHost.ts +++ b/src/gfx/easelHost.ts @@ -35,7 +35,7 @@ module Shumway.GFX { private _easel: Easel; private _group: Group; private _context: Shumway.Remoting.GFX.GFXChannelDeserializerContext; - private _content: Group; + protected _content: Group; private _fullscreen: boolean; constructor(easel: Easel) { diff --git a/src/gfx/test/playbackEaselHost.ts b/src/gfx/test/playbackEaselHost.ts index a9bbff7595..33947f3055 100644 --- a/src/gfx/test/playbackEaselHost.ts +++ b/src/gfx/test/playbackEaselHost.ts @@ -28,12 +28,15 @@ module Shumway.GFX.Test { export class PlaybackEaselHost extends EaselHost { private _parser: MovieRecordParser; private _lastTimestamp: number; + private intrinsicSizeInitialized: boolean = false; public ignoreTimestamps: boolean = false; + public useIntrinsicSize: boolean = false; public alwaysRenderFrame: boolean = false; public cpuTimeUpdates: number = 0; public cpuTimeRendering: number = 0; + public onFrame: () => void = null; public onComplete: () => void = null; public constructor(easel: Easel) { @@ -44,7 +47,11 @@ module Shumway.GFX.Test { return this.cpuTimeUpdates + this.cpuTimeRendering; } - private playUrl(url: string) { + public get currentPosition(): number { + return this._parser.position; + } + + playUrl(url: string) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'arraybuffer'; @@ -54,7 +61,7 @@ module Shumway.GFX.Test { xhr.send(); } - private playBytes(data: Uint8Array) { + playBytes(data: Uint8Array) { this._parser = new MovieRecordParser(data); this._lastTimestamp = 0; this._parseNext(); @@ -130,8 +137,8 @@ module Shumway.GFX.Test { } this.cpuTimeUpdates += performance.now() - start; - if (this._parser.currentType === MovieRecordType.Frame && - this.alwaysRenderFrame) { + + if (this._parser.currentType === MovieRecordType.Frame && this.alwaysRenderFrame) { requestAnimationFrame(this._renderFrameJustAfterRAF.bind(this)); } else { this._parseNext(); @@ -145,5 +152,19 @@ module Shumway.GFX.Test { this._parseNext(); } + + set fullscreen(value: boolean) { + // Hack: When this setter is called, the stage bounds are guaranteed to be set. + if (this.useIntrinsicSize && !this.intrinsicSizeInitialized) { + var bounds = this._content.getBounds(); + console.log(bounds); + this.easel.setSize(bounds.w, bounds.h); + this.intrinsicSizeInitialized = true; + } + } + + processFrame() { + this.onFrame && this.onFrame(); + } } } diff --git a/src/gfx/test/recorder.ts b/src/gfx/test/recorder.ts index 6ea0f53db2..1308a1963e 100644 --- a/src/gfx/test/recorder.ts +++ b/src/gfx/test/recorder.ts @@ -296,6 +296,10 @@ module Shumway.GFX.Test { this._buffer.position = 4; } + public get position(): number { + return this._buffer.position; + } + public readNextRecord(): MovieRecordType { if (this._buffer.position >= this._buffer.length) { return MovieRecordType.None; From c5f991d78913096a14586bc82827dc60388c1089 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Thu, 17 Sep 2015 19:09:27 +0200 Subject: [PATCH 2/2] Add encapsulated support for playing back base64-encoded SWFM files With intrinsic sizing, in a `DIV` identified by an `id`. --- src/gfx/test/playbackEaselHost.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/gfx/test/playbackEaselHost.ts b/src/gfx/test/playbackEaselHost.ts index 33947f3055..04db8e7d16 100644 --- a/src/gfx/test/playbackEaselHost.ts +++ b/src/gfx/test/playbackEaselHost.ts @@ -25,6 +25,21 @@ module Shumway.GFX.Test { var MINIMAL_TIMER_INTERVAL = 5; + export function playBase64SWFM(containerID: string, swfm: string) { + var container: HTMLDivElement = document.getElementById(containerID); + if (!container) { + throw new Error('DIV with id "' + containerID + '" not found'); + } + if (!swfm || typeof swfm !== 'string') { + throw new Error("No base64-encoded SWFM file provided"); + } + var easel = new Shumway.GFX.Easel(container); + var easelHost = new PlaybackEaselHost(easel); + easelHost.useIntrinsicSize = true; + easelHost.playBytes(Shumway.StringUtilities.decodeRestrictedBase64ToBytes(swfm)); + easel.startRendering(); + } + export class PlaybackEaselHost extends EaselHost { private _parser: MovieRecordParser; private _lastTimestamp: number;