Path: blob/main/test/browser/gl_in_pthread.c
7085 views
// Copyright 2016 The Emscripten Authors. All rights reserved.1// Emscripten is available under two separate licenses, the MIT license and the2// University of Illinois/NCSA Open Source License. Both these licenses can be3// found in the LICENSE file.45#include <stdio.h>6#include <string.h>7#include <pthread.h>8#include <GLES2/gl2.h>9#include <math.h>10#include <assert.h>11#include <emscripten/emscripten.h>12#include <emscripten/html5.h>13#include <emscripten/threading.h>14#include <bits/errno.h>15#include <stdlib.h>1617pthread_t thread;1819EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx;2021int numThreadsCreated = 0;2223int result = 0;2425void *ThreadMain(void *arg)26{27printf("ThreadMain\n");28switch(numThreadsCreated)29{30case 1: printf("Thread 1 started: you should see the WebGL canvas fade from black to red.\n"); break;31case 2: printf("Thread 2 started: you should see the WebGL canvas fade from black to green.\n"); break;32case 3: printf("Thread 3 started: you should see the WebGL canvas fade from black to blue.\n"); break;33}34EmscriptenWebGLContextAttributes attr;35emscripten_webgl_init_context_attributes(&attr);36attr.explicitSwapControl = true;37ctx = emscripten_webgl_create_context("#canvas", &attr);38emscripten_webgl_make_context_current(ctx);3940double color = 0;41for(int i = 0; i < 100; ++i)42{43color += 0.01;44switch(numThreadsCreated)45{46case 1: glClearColor(color, 0, 0, 1); break;47case 2: glClearColor(0, color, 0, 1); break;48case 3: glClearColor(0, 0, color, 1); break;49}50glClear(GL_COLOR_BUFFER_BIT);51EMSCRIPTEN_RESULT r = emscripten_webgl_commit_frame();52assert(r == EMSCRIPTEN_RESULT_SUCCESS);5354double now = emscripten_get_now();55while(emscripten_get_now() - now < 16) /*no-op*/;56}5758emscripten_webgl_make_context_current(0);59emscripten_webgl_destroy_context(ctx);60printf("Thread quit\n");61pthread_exit(0);62}6364void CreateThread()65{66pthread_attr_t attr;67pthread_attr_init(&attr);68emscripten_pthread_attr_settransferredcanvases(&attr, "#canvas");69int rc = pthread_create(&thread, &attr, ThreadMain, 0);70if (rc == ENOSYS)71{72printf("Test Skipped! OffscreenCanvas is not supported!\n");73#ifdef REPORT_RESULT74REPORT_RESULT(1); // But report success, so that runs on non-supporting browsers don't raise noisy errors.75#endif76exit(0);77}78if (rc)79{80printf("Failed to create thread! error: %d\n", rc);81exit(0);82}83pthread_attr_destroy(&attr);84++numThreadsCreated;85}8687void *mymain(void* arg)88{89for(int i = 0; i < 3; ++i)90{91printf("Creating thread %d\n", i+1);92CreateThread();93printf("Waiting for thread to finish.\n");94pthread_join(thread, 0);95thread = 0;96}97printf("All done!\n");98return 0;99}100101// Tests that the OffscreenCanvas context can travel from main thread -> thread 1 -> thread 2102// #define TEST_CHAINED_WEBGL_CONTEXT_PASSING103104// If set, the OffscreenCanvas is transferred from the main thread directly to thread 2, without giving it to thread 1105// in between.106// #define TRANSFER_TO_CHAINED_THREAD_FROM_MAIN_THREAD107108int main()109{110#ifdef TEST_CHAINED_WEBGL_CONTEXT_PASSING111pthread_attr_t attr;112pthread_attr_init(&attr);113#ifndef TRANSFER_TO_CHAINED_THREAD_FROM_MAIN_THREAD114emscripten_pthread_attr_settransferredcanvases(&attr, "#canvas");115#endif116int rc = pthread_create(&thread, &attr, mymain, 0);117if (rc == ENOSYS)118{119printf("Test Skipped! OffscreenCanvas is not supported!\n");120#ifdef REPORT_RESULT121REPORT_RESULT(1); // But report success, so that runs on non-supporting browsers don't raise noisy errors.122#endif123exit(0);124}125emscripten_exit_with_live_runtime();126#else127mymain(0);128#endif129return 0;130}131132133