author | Mason Chang <mchang@mozilla.com> |
Tue, 16 Jun 2015 15:49:26 -0700 (2015-06-16) | |
changeset 249257 | a53b5cee6b6f89f5c987b00060ab76f47614da08 |
parent 249256 | c80271e9f1c2e44905a72214800da01590f369c8 |
child 249258 | 6c05b6375d9feba15f298a4bdb079cca9e3a4488 |
push id | 28923 |
push user | ryanvm@gmail.com |
push date | Wed, 17 Jun 2015 18:57:11 +0000 (2015-06-17) |
treeherder | mozilla-central@099d6cd6725e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mattwoodrow, mossop |
bugs | 1156135 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -906,8 +906,14 @@ bin/libfreebl_32int64_3.so #endif ; media #ifdef MOZ_EME @RESPATH@/gmp-clearkey/0.1/@DLL_PREFIX@clearkey@DLL_SUFFIX@ @RESPATH@/gmp-clearkey/0.1/clearkey.info #endif + +; gfx +#ifdef XP_WIN +@RESPATH@/components/GfxSanityTest.manifest +@RESPATH@/components/SanityTest.js +#endif
new file mode 100644 --- /dev/null +++ b/toolkit/components/gfx/GfxSanityTest.manifest @@ -0,0 +1,3 @@ +component {f3a8ca4d-4c83-456b-aee2-6a2cbf11e9bd} SanityTest.js process=main +contract @mozilla.org/sanity-test;1 {f3a8ca4d-4c83-456b-aee2-6a2cbf11e9bd} process=main +category profile-after-change SanityTest @mozilla.org/sanity-test;1 process=main
new file mode 100644 --- /dev/null +++ b/toolkit/components/gfx/SanityTest.js @@ -0,0 +1,150 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { utils: Cu, interfaces: Ci, classes: Cc, results: Cr } = Components; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import('resource://gre/modules/Preferences.jsm'); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +const PAGE_WIDTH=72; +const PAGE_HEIGHT=136; +const DRIVER_PREF="sanity-test.driver-version"; +const DEVICE_PREF="sanity-test.device-id"; +const VERSION_PREF="sanity-test.version"; +const DISABLE_VIDEO_PREF="media.hardware-video-decoding.failed"; +const RUNNING_PREF="sanity-test.running"; + +// GRAPHICS_SANITY_TEST histogram enumeration values +const TEST_PASSED=0; +const TEST_FAILED_RENDER=1; +const TEST_FAILED_VIDEO=2; +const TEST_CRASHED=3; + +function testPixel(ctx, x, y, r, g, b, a, fuzz) { + var data = ctx.getImageData(x, y, 1, 1); + + if (Math.abs(data.data[0] - r) <= fuzz && + Math.abs(data.data[1] - g) <= fuzz && + Math.abs(data.data[2] - b) <= fuzz && + Math.abs(data.data[3] - a) <= fuzz) { + return true; + } + return false; +} + +function reportResult(val) { + try { + let histogram = Services.telemetry.getHistogramById("GRAPHICS_SANITY_TEST"); + histogram.add(val); + } catch (e) {} + + Preferences.set(RUNNING_PREF, false); + Services.prefs.savePrefFile(null); +} + +function takeWindowSnapshot(win) { + // Take a snapshot of the window contents, and then close the window + var canvas = win.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); + canvas.setAttribute("width", PAGE_WIDTH); + canvas.setAttribute("height", PAGE_HEIGHT); + + // TODO: drawWindow reads back from the gpu's backbuffer, which won't catch issues with presenting + // the front buffer via the window manager. Ideally we'd use an OS level API for reading back + // from the desktop itself to get a more accurate test. + var ctx = canvas.getContext("2d"); + var flags = ctx.DRAWWINDOW_DRAW_CARET | ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_USE_WIDGET_LAYERS; + ctx.drawWindow(win.ownerGlobal, 0, 0, PAGE_WIDTH, PAGE_HEIGHT, "rgb(255,255,255)", flags); + + win.ownerGlobal.close(); + return ctx; +} + +// Verify that all the 4 coloured squares of the video +// render as expected (with a tolerance of 64 to allow for +// yuv->rgb differences between platforms). +// +// The video is 64x64, and is split into quadrants of +// different colours. The top left of the video is 8,72 +// and we test a pixel 10,10 into each quadrant to avoid +// blending differences at the edges. +// +// We allow massive amounts of fuzz for the colours since +// it can depend hugely on the yuv -> rgb conversion, and +// we don't want to fail unnecessarily. +function verifyVideoRendering(ctx) { + return testPixel(ctx, 18, 82, 255, 255, 255, 255, 64) && + testPixel(ctx, 50, 82, 0, 255, 0, 255, 64) && + testPixel(ctx, 18, 114, 0, 0, 255, 255, 64) && + testPixel(ctx, 50, 114, 255, 0, 0, 255, 64); +} + +function testGfxFeatures(event) { + var win = event.target; + var canvas = takeWindowSnapshot(win); + + if (!verifyVideoRendering(canvas)) { + reportResult(TEST_FAILED_VIDEO); + Preferences.set(DISABLE_VIDEO_PREF, true); + } else { + reportResult(TEST_PASSED); + } +} + +function SanityTest() {} +SanityTest.prototype = { + classID: Components.ID("{f3a8ca4d-4c83-456b-aee2-6a2cbf11e9bd}"), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, + Ci.nsISupportsWeakReference]), + + shouldRunTest: function() { + // Only test gfx features if firefox has updated, or if the user has a new + // gpu or drivers. + var appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo); + var xulVersion = appInfo.version; + var gfxinfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); + + if (Preferences.get(RUNNING_PREF, false)) { + Preferences.set(DISABLE_VIDEO_PREF, true); + reportResult(TEST_CRASHED); + return false; + } + + // TODO: Handle dual GPU setups + if (Preferences.get(DRIVER_PREF, "") == gfxinfo.adapterDriverVersion && + Preferences.get(DEVICE_PREF, "") == gfxinfo.adapterDeviceID && + Preferences.get(VERSION_PREF, "") == xulVersion) { + return false; + } + + // Enable hardware decoding so we can test again + // and record the driver version to detect if the driver changes. + Preferences.set(DISABLE_VIDEO_PREF, false); + Preferences.set(DRIVER_PREF, gfxinfo.adapterDriverVersion); + Preferences.set(DEVICE_PREF, gfxinfo.adapterDeviceID); + Preferences.set(VERSION_PREF, xulVersion); + + // Update the prefs so that this test doesn't run again until the next update. + Preferences.set(RUNNING_PREF, true); + Services.prefs.savePrefFile(null); + return true; + }, + + observe: function(subject, topic, data) { + if (topic != "profile-after-change") return; + if (!this.shouldRunTest()) return; + + // Open a tiny window to render our test page, and notify us when it's loaded + var sanityTest = Services.ww.openWindow(null, + "chrome://gfxsanity/content/sanitytest.html", + "Test Page", + "width=" + PAGE_WIDTH + ",height=" + PAGE_HEIGHT + ",chrome,titlebar=0,scrollbars=0", + null); + sanityTest.onload = testGfxFeatures; + }, +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SanityTest]);
new file mode 100644 --- /dev/null +++ b/toolkit/components/gfx/content/sanitytest.html @@ -0,0 +1,6 @@ +<html> + <body> + <div style="width:64px; height:64px; background-color:red;"></div> + <video src="videotest.mp4"></video> + </body> +</html>
new file mode 100644 index 0000000000000000000000000000000000000000..42cf6e1aa6dfc6260ec535813bc753c3724f96e9 GIT binary patch literal 1563 zc$|$?UuYaf7@uouEg_;v#3~I;s%X{TWq0p##>0h33_YPiAKEA=tg|z-x7*v@nas>x z?n)n`1QC?_qIvK^A4L?4Pl7>EDE>hTf(QmmKm<_&`XEU0q3bu7rn$ye9Cl`Y^L@YX z`{w&*W)VU-GJTn7ks-7X*%`V=y41~N%|!?uj1=bxjog(nVt{l0z%51b!KL}%KKo^( z`N`U`AMwV0zyHzm>NQ-(R49(!nunEFtGbv>&s1GPK+&uKVQS%-`QzmpeqwPBn2b|U z%n8{~d1SEXIMuS}xYkW<jBHFzEiW%ux(VYVC3!`t)|8D>iA|OQM@W;1TsJT!A)&sD z6_5NXW;{#<ZToJ+X*ihVB<*YNJH2Yd>A7wdXWWl@59>|{=us?nA538k6!YDR14c05 zEa`C;SdT7P1d8M>?z?qNV<j>YfT@d(;%S;_Kr_7=MhyVEl=%*9fv__o=f3A2b6p$} zZ33y=iL{Ju2TL*#QKY%?%N{nd0t;~D;Z%q=iD4C76Jnhvl<x{0oU1_)nq<V-jU>6@ zDkVSyd6;$-=?7F~k{DQ1sF6`5$-xB>6|tO1k&J7oRv5@W;Dq@eV8V#BX@o(T5F3dl ziVqT7=1D6yAs``n9<+o6?Y2;YX`A=Kx9?3mS7DGPIV`cJJm<7y{F;LY(QQo?*D;tY z8eB`)>J{~=if|S}VQpHl@V#oq!Amw7->K9AO6zzqlb&CH41hLV`Zb(LI3>6daERcG zEWrh^$B9<p3NP|kSJ5NImA~}a(f0A`TMtg~hh9AU(U%`zJiWPj{=%Izw=X<DzyHMP zH($FrG4|ef>zB@Lz5VjZ+7FXYom(AUpSb+}r;`USzx&PD7vt!iuhzE~PNgSb54T=| z$FP|R(S-<U){Pmuu8sT(!%<X1_S<cx>sfo(v*<tDKIn%M!L(i6v9hvqD|)&piYo;; z`V-3A2Js7~J=n|04Wb<Vm&gCJpV=KydLv^A0e~~MH(zv*C7il2z~z{wYDZz8@Gx=F zKItaOS;{S^)POUM0E~CDfz#nF+|RakhZ$U)p)HPeREn?SzqJWdnAfz?Y>4xU{fpfs zO`FgxYQo&SDPwOtR6v=L177D!42>2)p}Si!f4K4F1FN>&`|a@c<IT0_O6Wkm_4Bt! zKDSod7(EnYryqvh(i_Na9|zr;ZPmzayD}<<_zv`-!;C$SXEQ#SZJQh}Jsg)JQl`Uc gJe;H&e&p!L`$kxY_riaj>=fVx=|<D_3Ot>E03pkH_5c6?
new file mode 100644 --- /dev/null +++ b/toolkit/components/gfx/jar.mn @@ -0,0 +1,8 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +toolkit.jar: +% content gfxsanity %content/gfxsanity/ + content/gfxsanity/sanitytest.html (content/sanitytest.html) + content/gfxsanity/videotest.mp4 (content/videotest.mp4)
new file mode 100644 --- /dev/null +++ b/toolkit/components/gfx/moz.build @@ -0,0 +1,15 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +toolkit = CONFIG['MOZ_WIDGET_TOOLKIT'] + +if toolkit == 'windows': + EXTRA_COMPONENTS += [ + 'GfxSanityTest.manifest', + 'SanityTest.js', + ] + +JAR_MANIFESTS += ['jar.mn']
--- a/toolkit/components/moz.build +++ b/toolkit/components/moz.build @@ -23,16 +23,17 @@ DIRS += [ 'diskspacewatcher', 'downloads', 'exthelper', 'filepicker', 'filewatcher', 'finalizationwitness', 'formautofill', 'find', + 'gfx', 'jsdownloads', 'mediasniffer', 'microformats', 'osfile', 'parentalcontrols', 'passwordmgr', 'perf', 'places',
--- a/widget/GfxInfoBase.cpp +++ b/widget/GfxInfoBase.cpp @@ -650,16 +650,17 @@ GfxInfoBase::GfxInfoBase() GfxInfoBase::~GfxInfoBase() { } nsresult GfxInfoBase::Init() { InitGfxDriverInfoShutdownObserver(); + gfxPrefs::GetSingleton(); nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) { os->AddObserver(this, "blocklist-data-gfxItems", true); } return NS_OK; }