Add support for specifying the canvas image filtering algorithm in fullscreen mode.

This commit is contained in:
Jukka Jylänki 2014-11-06 23:25:04 +02:00
Родитель e3f19a4a73
Коммит ba0094639c
5 изменённых файлов: 52 добавлений и 20 удалений

Просмотреть файл

@ -618,6 +618,11 @@ var LibraryJSEvents = {
target.style.width = cssWidth + 'px';
target.style.height = cssHeight + 'px';
if (strategy.filteringMode == {{{ cDefine('EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST') }}}) {
target.style.imageRendering = '-moz-crisp-edges';
target.style['-ms-interpolation-mode'] = 'nearest-neighbor';
}
var dpiScale = (strategy.canvasResolutionScaleMode == {{{ cDefine('EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF') }}}) ? window.devicePixelRatio : 1;
if (strategy.canvasResolutionScaleMode != {{{ cDefine('EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE') }}}) {
target.width = cssWidth * dpiScale;
@ -1218,7 +1223,10 @@ var LibraryJSEvents = {
var oldDocumentBodyMargin = document.body.style.margin;
var oldDocumentOverflow = document.documentElement.style.overflow; // Chrome, Firefox
var oldDocumentScroll = document.body.scroll; // IE
function restoreOldStyle() {
var oldImageRendering = canvas.style.imageRendering;
var oldInterpolationMode = canvas.style['-ms-interpolation-mode'];
function restoreOldStyle() {
var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
if (!fullscreenElement) {
document.removeEventListener('fullscreenchange', restoreOldStyle);
@ -1247,6 +1255,8 @@ var LibraryJSEvents = {
document.body.style.margin = oldDocumentBodyMargin;
document.documentElement.style.overflow = oldDocumentOverflow; // Chrome, Firefox
document.body.scroll = oldDocumentScroll; // IE
canvas.style.imageRendering = oldImageRendering;
canvas.style['-ms-interpolation-mode'] = oldInterpolationMode;
if (canvas.GLctxObject) canvas.GLctxObject.GLctx.viewport(0, 0, oldWidth, oldHeight);
if (__currentFullscreenStrategy.canvasResizedCallback) {
@ -1400,6 +1410,7 @@ var LibraryJSEvents = {
// These options perform no added logic, but just bare request fullscreen.
strategy.scaleMode = {{{ cDefine('EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT') }}};
strategy.canvasResolutionScaleMode = {{{ cDefine('EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE') }}};
strategy.filteringMode = {{{ cDefine('EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT') }}};
strategy.deferUntilInEventHandler = deferUntilInEventHandler;
return _emscripten_do_request_fullscreen(target, strategy);
@ -1410,6 +1421,7 @@ var LibraryJSEvents = {
var strategy = {};
strategy.scaleMode = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.scaleMode, 'i32') }}};
strategy.canvasResolutionScaleMode = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.canvasResolutionScaleMode, 'i32') }}};
strategy.filteringMode = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.filteringMode, 'i32') }}};
strategy.deferUntilInEventHandler = deferUntilInEventHandler;
strategy.canvasResizedCallback = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.canvasResizedCallback, 'i32') }}};
strategy.canvasResizedCallbackUserData = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.canvasResizedCallbackUserData, 'i32') }}};
@ -1427,6 +1439,7 @@ var LibraryJSEvents = {
var strategy = {};
strategy.scaleMode = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.scaleMode, 'i32') }}};
strategy.canvasResolutionScaleMode = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.canvasResolutionScaleMode, 'i32') }}};
strategy.filteringMode = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.filteringMode, 'i32') }}};
strategy.canvasResizedCallback = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.canvasResizedCallback, 'i32') }}};
strategy.canvasResizedCallbackUserData = {{{ makeGetValue('fullscreenStrategy', C_STRUCTS.EmscriptenFullscreenStrategy.canvasResizedCallbackUserData, 'i32') }}};
strategy.target = target;

Просмотреть файл

@ -1174,7 +1174,10 @@
"EMSCRIPTEN_FULLSCREEN_SCALE_CENTER",
"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE",
"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF",
"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF"
"EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF",
"EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT",
"EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST",
"EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR"
],
"structs": {
"EmscriptenKeyboardEvent": [
@ -1332,6 +1335,7 @@
"EmscriptenFullscreenStrategy": [
"scaleMode",
"canvasResolutionScaleMode",
"filteringMode",
"canvasResizedCallback",
"canvasResizedCallbackUserData"
]

Просмотреть файл

@ -256,11 +256,17 @@ extern EMSCRIPTEN_RESULT emscripten_get_fullscreen_status(EmscriptenFullscreenCh
#define EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF 1
#define EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF 2
#define EMSCRIPTEN_FULLSCREEN_FILTERING int
#define EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT 0
#define EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST 1
#define EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR 2
typedef EM_BOOL (*em_canvasresized_callback_func)(int eventType, const void *reserved, void *userData);
typedef struct EmscriptenFullscreenStrategy {
EMSCRIPTEN_FULLSCREEN_SCALE scaleMode;
EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE canvasResolutionScaleMode;
EMSCRIPTEN_FULLSCREEN_FILTERING filteringMode;
em_canvasresized_callback_func canvasResizedCallback;
void *canvasResizedCallbackUserData;
} EmscriptenFullscreenStrategy;

Просмотреть файл

@ -125,23 +125,25 @@ EM_BOOL on_canvassize_changed(int eventType, const void *reserved, void *userDat
return 0;
}
void requestFullscreen(int scaleMode, int canvasResolutionScaleMode)
void requestFullscreen(int scaleMode, int canvasResolutionScaleMode, int filteringMode)
{
EmscriptenFullscreenStrategy s;
memset(&s, 0, sizeof(s));
s.scaleMode = scaleMode;
s.canvasResolutionScaleMode = canvasResolutionScaleMode;
s.filteringMode = filteringMode;
s.canvasResizedCallback = on_canvassize_changed;
EMSCRIPTEN_RESULT ret = emscripten_request_fullscreen_strategy(0, 1, &s);
TEST_RESULT(requestFullscreen);
}
void enterSoftFullscreen(int scaleMode, int canvasResolutionScaleMode)
void enterSoftFullscreen(int scaleMode, int canvasResolutionScaleMode, int filteringMode)
{
EmscriptenFullscreenStrategy s;
memset(&s, 0, sizeof(s));
s.scaleMode = scaleMode;
s.canvasResolutionScaleMode = canvasResolutionScaleMode;
s.filteringMode = filteringMode;
s.canvasResizedCallback = on_canvassize_changed;
EMSCRIPTEN_RESULT ret = emscripten_enter_soft_fullscreen(0, &s);
TEST_RESULT(enterSoftFullscreen);
@ -151,22 +153,25 @@ int on_button_click(int eventType, const EmscriptenMouseEvent *mouseEvent, void
{
switch((int)userData)
{
case 0: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE); break;
case 1: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF); break;
case 2: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF); break;
case 3: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF); break;
case 4: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF); break;
case 5: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE); break;
case 6: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE); break;
case 7: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_CENTER, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE); break;
case 0: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 1: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 2: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 3: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 4: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 5: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 6: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 7: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_CENTER, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 8: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF); break;
case 9: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF); break;
case 10: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF); break;
case 11: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF); break;
case 12: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE); break;
case 13: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE); break;
case 14: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_CENTER, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE); break;
case 8: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 9: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 10: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 11: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 12: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 13: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 14: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_CENTER, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT); break;
case 15: requestFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST); break;
case 16: enterSoftFullscreen(EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE, EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST); break;
default: return 0;
}
return 1;
@ -241,6 +246,8 @@ int main()
emscripten_set_click_callback("b12", (void*)12, 1, on_button_click);
emscripten_set_click_callback("b13", (void*)13, 1, on_button_click);
emscripten_set_click_callback("b14", (void*)14, 1, on_button_click);
emscripten_set_click_callback("b15", (void*)15, 1, on_button_click);
emscripten_set_click_callback("b16", (void*)16, 1, on_button_click);
printf("To finish this test, press f to enter fullscreen mode, and then exit it.\n");
printf("On IE, press a mouse key over the canvas after pressing f to activate the fullscreen request event.\n");

Просмотреть файл

@ -157,6 +157,7 @@
<input type="button" id="b4" value="Aspect+HiDPI"> Same as above, but use the actual native display resolution, instead of CSS resolution. <br />
<input type="button" id="b5" value="Stretch+None"> Don't resize WebGL render target, and don't care about aspect ratio, simply stretch over the whole screen. (current Firefox and IE default behavior) <br />
<input type="button" id="b6" value="Aspect+None"> Don't resize WebGL render target, but scale over the whole screen, preserving aspect ratio. <br />
<input type="button" id="b15" value="Aspect+None+Nearest"> Same as above, but perform pixelated nearest-neighbor filtering instead of bilinear filtering. <br />
<input type="button" id="b7" value="Center"> Don't resize the WebGL render target and don't scale the displayed content, but show it full screen. (current Chrome and Safari default behavior) <br />
<div>
<br />
@ -168,7 +169,8 @@
<input type="button" id="b11" value="Aspect+HiDPI"> <br />
<input type="button" id="b12" value="Strech+None"> <br />
<input type="button" id="b13" value="Aspect+None"> <br />
<input type="button" id="b14" value="Center"> Don't resize the WebGL render target and don't scale the displayed content, but show it full screen. <br />
<input type="button" id="b16" value="Aspect+None+Nearest"> <br />
<input type="button" id="b14" value="Center"> <br />
</div>
</div>