summaryrefslogtreecommitdiff
path: root/src/test/OffscreenTest.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/OffscreenTest.py')
-rw-r--r--src/test/OffscreenTest.py472
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()