diff options
Diffstat (limited to 'src/test/OffscreenTest.py')
-rw-r--r-- | src/test/OffscreenTest.py | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/src/test/OffscreenTest.py b/src/test/OffscreenTest.py new file mode 100644 index 0000000..76bff52 --- /dev/null +++ b/src/test/OffscreenTest.py @@ -0,0 +1,472 @@ +# -*- coding: utf-8 -*- +# libavg - Media Playback Engine. +# Copyright (C) 2003-2014 Ulrich von Zadow +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Current versions can be found at www.libavg.de +# + +from libavg import avg, player +from testcase import * +import gc + +class OffscreenTestCase(AVGTestCase): + def __init__(self, testFuncName): + AVGTestCase.__init__(self, testFuncName) + + def testCanvasBasics(self): + def createCanvas(isFirst, canvasName, x): + canvas = self.__createOffscreenCanvas(canvasName, False) + canvas.getElementByID("test1").x = x + node = avg.ImageNode(parent=root, id="imagenode") + node.href="canvas:"+canvasName + if isFirst: + self.assertEqual(canvas.getNumDependentCanvases(), 0) + self.canvas1 = canvas + else: + self.assertEqual(canvas.getNumDependentCanvases(), 1) + self.canvas2 = canvas + + def unlink(): + self.node = player.getElementByID("imagenode") + self.node.unlink() + self.assertEqual(self.canvas1.getNumDependentCanvases(), 0) + gc.collect() + + def relink(): + root.appendChild(self.node) + self.node = None + self.assertEqual(self.canvas1.getNumDependentCanvases(), 1) + + def changeHRef(href): + player.getElementByID("imagenode").href = href + + def setBitmap(): + bitmap = avg.Bitmap("media/rgb24-65x65.png") + player.getElementByID("imagenode").setBitmap(bitmap) + + def deleteCanvases(): + changeHRef("") + firstNode.href = "" + player.deleteCanvas("testcanvas1") +# self.assertException(lambda: changeHRef("canvas:testcanvas1")) + changeHRef("canvas:testcanvas2") +# self.assertException(lambda: player.deleteCanvas("testcanvas2")) + changeHRef("") + player.deleteCanvas("testcanvas2") +# self.assertException(lambda: player.deleteCanvas("foo")) + + root = self.loadEmptyScene() + root.mediadir = "media" + createCanvas(True, "testcanvas1", 0) + firstNode = player.getElementByID("imagenode") + self.start(False, + (lambda: self.compareImage("testOffscreen1"), + unlink, + lambda: self.compareImage("testOffscreen2"), + relink, + lambda: self.compareImage("testOffscreen1"), + unlink, + lambda: createCanvas(False, "testcanvas2", 80), + lambda: self.compareImage("testOffscreen3"), + lambda: changeHRef("canvas:testcanvas1"), + lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 1), + lambda: self.assertEqual(self.canvas2.getNumDependentCanvases(), 0), + lambda: self.compareImage("testOffscreen1"), + lambda: changeHRef("rgb24-65x65.png"), + lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 0), + lambda: self.compareImage("testOffscreen4"), + lambda: changeHRef("canvas:testcanvas1"), + lambda: self.assertEqual(self.canvas1.getNumDependentCanvases(), 1), + lambda: self.compareImage("testOffscreen1"), + setBitmap, + lambda: self.compareImage("testOffscreen4"), + deleteCanvases, + lambda: self.compareImage("testOffscreen5"), + )) + + def testCanvasLoadAfterPlay(self): + def createOffscreenCanvas(): + self.__createOffscreenCanvas("offscreencanvas", False) + self.node = avg.ImageNode(parent=root, href="canvas:offscreencanvas") + + root = self.loadEmptyScene() + self.start(False, + (createOffscreenCanvas, + lambda: self.compareImage("testOffscreen1"), + )) + + def testCanvasResize(self): + def setSize(): + self.node.size = (80, 60) + + mainCanvas, offscreenCanvas = self.__setupCanvas(False) + self.start(False, + (setSize, + lambda: self.compareImage("testCanvasResize") + )) + + def testCanvasErrors(self): + self.loadEmptyScene() + # Missing size + self.assertException( + lambda: player.createCanvas(id="foo")) + # Duplicate canvas id + player.createCanvas(id="foo", size=(160, 120)) + self.assertException( + lambda: player.createCanvas(id="foo", size=(160, 120))) + + def testCanvasAPI(self): + def checkMainScreenshot(): + bmp1 = player.screenshot() + bmp2 = mainCanvas.screenshot() + self.assert_(self.areSimilarBmps(bmp1, bmp2, 0.01, 0.01)) + + def checkCanvasScreenshot(): + bmp = offscreenCanvas.screenshot() + self.compareBitmapToFile(bmp, "testOffscreenScreenshot") + + def createCompressed(): + avg.ImageNode(href="canvas:offscreencanvas", compression="B5G6R5", + parent=root) + + root = self.loadEmptyScene() + mainCanvas = player.getMainCanvas() + self.assertEqual(mainCanvas.getRootNode(), root) + offscreenCanvas = self.__createOffscreenCanvas("offscreencanvas", False) + self.assertEqual(offscreenCanvas, player.getCanvas("offscreencanvas")) + self.assertEqual(offscreenCanvas.getElementByID("test1").href, "rgb24-65x65.png") + self.assertEqual(offscreenCanvas.getElementByID("missingnode"), None) + self.assertException(player.screenshot) + self.assertException(createCompressed) + self.start(False, + (checkMainScreenshot, + checkCanvasScreenshot)) + + def testCanvasEvents(self): + def onOffscreenImageDown(event): + self.__offscreenImageDownCalled = True + + def onMainDown(event): + self.__mainDownCalled = True + + def reset(): + self.__offscreenImageDownCalled = False + self.__mainDownCalled = False + + def setPos(): + self.node.pos = (80, 60) + self.node.size = (80, 60) + + mainCanvas, offscreenCanvas = self.__setupCanvas(True) + offscreenImage = offscreenCanvas.getElementByID("test1") + offscreenImage.subscribe(avg.Node.CURSOR_DOWN, onOffscreenImageDown) + player.getRootNode().subscribe(avg.Node.CURSOR_DOWN, onMainDown) + self.__offscreenImageDownCalled = False + self.__mainDownCalled = False + self.start(False, + (lambda: self.fakeClick(10, 10), + lambda: self.assert_(self.__offscreenImageDownCalled), + reset, + lambda: self.fakeClick(80, 10), + lambda: self.assert_(not(self.__offscreenImageDownCalled)), + reset, + setPos, + lambda: self.fakeClick(70, 65), + lambda: self.assert_(not(self.__offscreenImageDownCalled)), + lambda: self.fakeClick(120, 65), + lambda: self.assert_(not(self.__offscreenImageDownCalled)), + reset, + lambda: self.fakeClick(110, 65), + lambda: self.assert_(self.__offscreenImageDownCalled and + self.__mainDownCalled), + reset, + lambda: self.fakeClick(1, 1), + lambda: self.assert_(not(self.__offscreenImageDownCalled) and + self.__mainDownCalled), + )) + + def testCanvasEventCapture(self): + def onOffscreenImageDown(event): + self.__offscreenImageDownCalled = True + + mainCanvas, offscreenCanvas = self.__setupCanvas(True) + offscreenImage = offscreenCanvas.getElementByID("test1") + offscreenImage.subscribe(avg.Node.CURSOR_DOWN, onOffscreenImageDown); + self.__offscreenImageDownCalled = False + offscreenImage.setEventCapture() + self.start(False, + (lambda: self._sendMouseEvent(avg.Event.CURSOR_DOWN, 80, 10), + lambda: self.assert_(self.__offscreenImageDownCalled), + )) + + def testCanvasRender(self): + def createCanvas(): + canvas = player.createCanvas(id="testcanvas", size=(160,120), + mediadir="media", autorender=False) + avg.ImageNode(id="test", href="rgb24-65x65.png", parent=canvas.getRootNode()) + return canvas + + def testEarlyScreenshotException(): + self.assertException(self.__offscreenCanvas.screenshot) + + def renderCanvas(): + self.__offscreenCanvas.render() + bmp = self.__offscreenCanvas.screenshot() + self.compareBitmapToFile(bmp, "testOffscreenScreenshot") + + def deleteCanvas(): + player.deleteCanvas("testcanvas") + self.__offscreenCanvas = None + + def recreateCanvas(): + self.__offscreenCanvas = createCanvas() + + self.loadEmptyScene() + self.__offscreenCanvas = createCanvas() + self.assertException(renderCanvas) + self.start(False, + (testEarlyScreenshotException, + renderCanvas, + deleteCanvas, + recreateCanvas, + renderCanvas + )) + + def testCanvasAutoRender(self): + def createCanvas(): + canvas = self.__createOffscreenCanvas("testcanvas", False) + avg.ImageNode(href="canvas:testcanvas", parent=root) + return canvas + + def disableAutoRender(): + self.__offscreenCanvas.autorender = False + + def enableAutoRender(): + self.__offscreenCanvas.autorender = True + + def changeContent(): + self.__offscreenCanvas.getElementByID("test1").x = 42 + + root = self.loadEmptyScene() + self.__offscreenCanvas = createCanvas() + self.start(False, + (lambda: self.assert_(self.__offscreenCanvas.autorender), + lambda: self.compareImage("testOffscreenAutoRender1"), + disableAutoRender, + lambda: self.assert_(not(self.__offscreenCanvas.autorender)), + changeContent, + lambda: self.compareImage("testOffscreenAutoRender1"), + enableAutoRender, + lambda: self.assert_(self.__offscreenCanvas.autorender), + lambda: self.compareImage("testOffscreenAutoRender2") + )) + + def testCanvasCrop(self): + root = self.loadEmptyScene() + canvas = player.createCanvas(id="testcanvas", size=(160,120), + mediadir="media") + div = avg.DivNode(pos=(40,30), size=(80,60), crop=True, + parent=canvas.getRootNode()) + avg.ImageNode(id="test1", pos=(-32, -32), href="rgb24-65x65.png", parent=div) + avg.ImageNode(parent=root, href="canvas:testcanvas") + self.start(False, (lambda: self.compareImage("testCanvasCrop"),)) + + def testCanvasAlpha(self): + root = self.loadEmptyScene() + canvas = player.createCanvas(id="testcanvas", size=(80,120), mediadir="media") + avg.ImageNode(id="test1", href="rgb24alpha-64x64.png", + parent=canvas.getRootNode()) + avg.RectNode(parent=root, fillcolor="FFFFFF", + pos=(0.5, 0.5), size=(160, 48), fillopacity=1) + avg.ImageNode(parent=root, href="canvas:testcanvas") + avg.ImageNode(parent=root, x=64, href="rgb24alpha-64x64.png") + self.start(False, (lambda: self.compareImage("testCanvasAlpha"),)) + + def testCanvasBlendModes(self): + def createBaseCanvas(): + canvas = player.createCanvas(id="testcanvas", size=(64,64), + mediadir="media") + avg.ImageNode(href="rgb24alpha-64x64.png", parent=canvas.getRootNode()) + return canvas + + root = self.loadEmptyScene() + createBaseCanvas() + avg.RectNode(parent=root, pos=(48,0), size=(32, 120), strokewidth=2, + fillopacity=1, fillcolor="808080") + avg.ImageNode(parent=root, href="canvas:testcanvas") + avg.ImageNode(parent=root, pos=(0,64), href="canvas:testcanvas", + opacity=0.6) + avg.ImageNode(parent=root, pos=(64,0), href="canvas:testcanvas", + blendmode="add") + avg.ImageNode(parent=root, pos=(64,64), href="canvas:testcanvas", + opacity=0.6, blendmode="add") + self.start(False, (lambda: self.compareImage("testCanvasBlendModes"),)) + + def testCanvasMultisampling(self): + def testIllegalSamples(numSamples): + self.canvas = player.createCanvas(id="brokencanvas", size=(160,120), + multisamplesamples=numSamples) + + def screenshot(): + bmp = self.canvas.screenshot() + self.compareBitmapToFile(bmp, "testOffscreenMultisampleScreenshot") + + def createCanvas(): + if not(avg.OffscreenCanvas.isMultisampleSupported()): + self.skip("Offscreen multisampling not supported") + player.stop() + return + try: + self.canvas = player.createCanvas(id="testcanvas", size=(160,120), + mediadir="media", multisamplesamples=2) + avg.ImageNode(id="test1", href="rgb24-65x65.png", angle=0.1, + parent=self.canvas.getRootNode()) + except RuntimeError: + self.skip("Offscreen multisampling init failed") + player.stop() + return + self.assertEqual(self.canvas.multisamplesamples, 2) + avg.ImageNode(parent=root, href="canvas:testcanvas") + + + root = self.loadEmptyScene() + self.start(False, + (createCanvas, + lambda: self.compareImage("testCanvasMultisample"), + screenshot, + lambda: self.assertException(lambda: testIllegalSamples(42)), + lambda: self.assertException(lambda: testIllegalSamples(0)), + )) + self.canvas = None + + def testCanvasMipmap(self): + root = self.loadEmptyScene() + + canvas = player.createCanvas(id="testcanvas", size=(80,120), mediadir="media", + mipmap=True) + avg.ImageNode(id="test1", href="rgb24alpha-64x64.png", + parent=canvas.getRootNode()) + avg.ImageNode(parent=root, size=(40, 30), href="canvas:testcanvas") + try: + self.start(False, (lambda: self.compareImage("testCanvasMipmap"),)) + except RuntimeError: + self.skip("Offscreen mipmap init failed.") + return + + def testCanvasDependencies(self): + def makeCircularRef(): + self.offscreen1.getElementByID("test1").href = "canvas:offscreencanvas2" + + def makeSelfRef1(): + avg.ImageNode(href="canvas:offscreencanvas1", + parent=self.offscreen1.getRootNode()) + + def makeSelfRef2(): + self.offscreen1.getElementByID("test1").href = "canvas:offscreencanvas1" + + def createTwoCanvases(): + self.offscreen1 = self.__createOffscreenCanvas("offscreencanvas1", False) + self.offscreen2 = self.__createOffscreenCanvas("offscreencanvas2", False) + self.node = avg.ImageNode(parent=root, + href="canvas:offscreencanvas1") + node = self.offscreen1.getElementByID("test1") + node.href = "canvas:offscreencanvas2" + node.size = (80, 60) + + def exchangeCanvases(): + self.offscreen1.getElementByID("test1").href = "rgb24-65x65.png" + self.offscreen2.getElementByID("test1").href = "canvas:offscreencanvas1" + self.node.href = "canvas:offscreencanvas2" + + def loadCanvasDepString(): + player.createCanvas(id="canvas1", size=(160, 120)) + canvas2 = player.createCanvas(id="canvas2", size=(160, 120)) + avg.ImageNode(href="canvas:canvas1", parent=canvas2.getRootNode()) + player.deleteCanvas('canvas2') + player.deleteCanvas('canvas1') + + root = self.loadEmptyScene() + createTwoCanvases() + self.offscreen1.getElementByID("test1").href = "" + self.offscreen1 = None + self.offscreen2 = None + self.node.href = "" + self.node = None + player.deleteCanvas("offscreencanvas1") + player.deleteCanvas("offscreencanvas2") + self.start(False, + (createTwoCanvases, + lambda: self.compareImage("testCanvasDependencies1"), + exchangeCanvases, + lambda: self.compareImage("testCanvasDependencies2"), + lambda: self.assertException(makeCircularRef), + lambda: self.assertException(makeSelfRef1), + lambda: self.assertException(makeSelfRef2), + loadCanvasDepString, + )) + + def __setupCanvas(self, handleEvents): + root = self.loadEmptyScene() + mainCanvas = player.getMainCanvas() + offscreenCanvas = self.__createOffscreenCanvas("offscreencanvas", handleEvents) + self.node = avg.ImageNode(parent=root, href="canvas:offscreencanvas") + return (mainCanvas, offscreenCanvas) + + def __createOffscreenCanvas(self, canvasName, handleEvents): + canvas = player.createCanvas(id=canvasName, size=(160,120), + handleevents=handleEvents) + canvas.getRootNode().mediadir = "media" + avg.ImageNode(id="test1", href="rgb24-65x65.png", parent=canvas.getRootNode()) + return canvas + +def isOffscreenSupported(): + + def testOffscreenSupported(): + global offscreenSupported + offscreenSupported = avg.OffscreenCanvas.isSupported() + player.stop() + + global offscreenSupported + sceneString = """<avg id="avg" width="160" height="120"/>""" + player.loadString(sceneString) + player.setTimeout(0, testOffscreenSupported) + player.play() + return offscreenSupported + +def offscreenTestSuite(tests): + if isOffscreenSupported(): + availableTests = ( + "testCanvasBasics", + "testCanvasLoadAfterPlay", + "testCanvasResize", + "testCanvasErrors", + "testCanvasAPI", + "testCanvasEvents", + "testCanvasEventCapture", + "testCanvasRender", + "testCanvasAutoRender", + "testCanvasCrop", + "testCanvasAlpha", + "testCanvasBlendModes", + "testCanvasMultisampling", + "testCanvasMipmap", + "testCanvasDependencies", + ) + return createAVGTestSuite(availableTests, OffscreenTestCase, tests) + else: + sys.stderr.write("Skipping offscreen tests - no canvas support with this graphics configuration.\n") + return unittest.TestSuite() |