Merge remote-tracking branch 'nasa/open-master' into open-master

This commit is contained in:
Victor Woeltjen 2015-06-24 10:06:10 -07:00
commit 47647f4ada
2 changed files with 34 additions and 5 deletions

View File

@ -155,6 +155,16 @@ define(
} }
} }
// Switch from WebGL to plain 2D if context is lost
function fallbackFromWebGL() {
element.html(TEMPLATE);
canvas = element.find("canvas")[0];
chart = getChart([Canvas2DChart], canvas);
if (chart) {
doDraw(scope.draw);
}
}
// Try to initialize a chart. // Try to initialize a chart.
chart = getChart([GLChart, Canvas2DChart], canvas); chart = getChart([GLChart, Canvas2DChart], canvas);
@ -164,6 +174,11 @@ define(
return; return;
} }
// WebGL is a bit of a special case; it may work, then fail
// later for various reasons, so we need to listen for this
// and fall back to plain canvas drawing when it occurs.
canvas.addEventListener("webglcontextlost", fallbackFromWebGL);
// Check for resize, on a timer // Check for resize, on a timer
activeInterval = $interval(drawIfResized, 1000); activeInterval = $interval(drawIfResized, 1000);
@ -192,4 +207,4 @@ define(
return MCTChart; return MCTChart;
} }
); );

View File

@ -36,6 +36,7 @@ define(
mockElement, mockElement,
mockCanvas, mockCanvas,
mockGL, mockGL,
mockC2d,
mockPromise, mockPromise,
mctChart; mctChart;
@ -47,13 +48,14 @@ define(
mockScope = mockScope =
jasmine.createSpyObj("$scope", ["$watchCollection", "$on"]); jasmine.createSpyObj("$scope", ["$watchCollection", "$on"]);
mockElement = mockElement =
jasmine.createSpyObj("element", ["find"]); jasmine.createSpyObj("element", ["find", "html"]);
mockInterval.cancel = jasmine.createSpy("cancelInterval"); mockInterval.cancel = jasmine.createSpy("cancelInterval");
mockPromise = jasmine.createSpyObj("promise", ["then"]); mockPromise = jasmine.createSpyObj("promise", ["then"]);
// mct-chart uses GLChart, so it needs WebGL API // mct-chart uses GLChart, so it needs WebGL API
mockCanvas = jasmine.createSpyObj("canvas", [ "getContext" ]); mockCanvas =
jasmine.createSpyObj("canvas", [ "getContext", "addEventListener" ]);
mockGL = jasmine.createSpyObj( mockGL = jasmine.createSpyObj(
"gl", "gl",
[ [
@ -81,6 +83,7 @@ define(
"drawArrays" "drawArrays"
] ]
); );
mockC2d = jasmine.createSpyObj('c2d', ['clearRect']);
mockGL.ARRAY_BUFFER = "ARRAY_BUFFER"; mockGL.ARRAY_BUFFER = "ARRAY_BUFFER";
mockGL.DYNAMIC_DRAW = "DYNAMIC_DRAW"; mockGL.DYNAMIC_DRAW = "DYNAMIC_DRAW";
mockGL.TRIANGLE_FAN = "TRIANGLE_FAN"; mockGL.TRIANGLE_FAN = "TRIANGLE_FAN";
@ -93,7 +96,9 @@ define(
}); });
mockElement.find.andReturn([mockCanvas]); mockElement.find.andReturn([mockCanvas]);
mockCanvas.getContext.andReturn(mockGL); mockCanvas.getContext.andCallFake(function (type) {
return { webgl: mockGL, '2d': mockC2d }[type];
});
mockInterval.andReturn(mockPromise); mockInterval.andReturn(mockPromise);
mctChart = new MCTChart(mockInterval, mockLog); mctChart = new MCTChart(mockInterval, mockLog);
@ -169,6 +174,15 @@ define(
expect(mockLog.warn).toHaveBeenCalled(); expect(mockLog.warn).toHaveBeenCalled();
}); });
it("falls back to Canvas 2d API if WebGL context is lost", function () {
mctChart.link(mockScope, mockElement);
expect(mockCanvas.addEventListener)
.toHaveBeenCalledWith("webglcontextlost", jasmine.any(Function));
expect(mockCanvas.getContext).not.toHaveBeenCalledWith('2d');
mockCanvas.addEventListener.mostRecentCall.args[1]();
expect(mockCanvas.getContext).toHaveBeenCalledWith('2d');
});
it("logs nothing in nominal situations (WebGL available)", function () { it("logs nothing in nominal situations (WebGL available)", function () {
// Complement the previous test // Complement the previous test
mctChart.link(mockScope, mockElement); mctChart.link(mockScope, mockElement);
@ -197,4 +211,4 @@ define(
}); });
} }
); );