Advertisement
dark-s0ul

Untitled

Sep 21st, 2017
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.46 KB | None | 0 0
  1. struct GLSurfaceView {
  2.     GLSurfaceView() {}
  3.  
  4.     void setGLWrapper(GLWrapper glWrapper) {
  5.         mGLWrapper = glWrapper;
  6.     }
  7.  
  8.     void setRenderer(Renderer renderer) {
  9.         checkRenderThreadState();
  10.         if (mEGLConfigChooser == nullptr) {
  11.             mEGLConfigChooser = new SimpleEGLConfigChooser(true);
  12.         }
  13.         if (mEGLContextFactory == nullptr) {
  14.             mEGLContextFactory = new DefaultContextFactory();
  15.         }
  16.         if (mEGLWindowSurfaceFactory == nullptr) {
  17.             mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
  18.         }
  19.         mRenderer = renderer;
  20.         mGLThread = new GLThread(mThisWeakRef);
  21.         mGLThread.start();
  22.     }
  23.  
  24.     void setEGLContextFactory(EGLContextFactory factory) {
  25.         checkRenderThreadState();
  26.         mEGLContextFactory = factory;
  27.     }
  28.  
  29.     void setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {
  30.         checkRenderThreadState();
  31.         mEGLWindowSurfaceFactory = factory;
  32.     }
  33.  
  34.     void setEGLConfigChooser(EGLConfigChooser configChooser) {
  35.         checkRenderThreadState();
  36.         mEGLConfigChooser = configChooser;
  37.     }
  38.  
  39.     void setEGLConfigChooser(bool needDepth) {
  40.         setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth));
  41.     }
  42.  
  43.     void setEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize) {
  44.         setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize));
  45.     }
  46.  
  47.     void setEGLContextClientVersion(int version) {
  48.         checkRenderThreadState();
  49.         mEGLContextClientVersion = version;
  50.     }
  51.  
  52.     void setRenderMode(int renderMode) {
  53.         mGLThread.setRenderMode(renderMode);
  54.     }
  55.  
  56.     void requestRender() {
  57.         mGLThread.requestRender();
  58.     }
  59.  
  60.     void surfaceCreated(SurfaceHolder holder) {
  61.         mGLThread.surfaceCreated();
  62.     }
  63.  
  64.     void surfaceDestroyed(SurfaceHolder holder) {
  65.         mGLThread.surfaceDestroyed();
  66.     }
  67.  
  68.     void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
  69.         mGLThread.onWindowResize(w, h);
  70.     }
  71.  
  72.     void surfaceRedrawNeededAsync(SurfaceHolder holder, Runnable finishDrawing) {
  73.         if (mGLThread != nullptr) {
  74.             mGLThread.requestRenderAndNotify(finishDrawing);
  75.         }
  76.     }
  77.  
  78.     void onPause() {
  79.         mGLThread.onPause();
  80.     }
  81.  
  82.     void onResume() {
  83.         mGLThread.onResume();
  84.     }
  85.  
  86.     void queueEvent(Runnable r) {
  87.         mGLThread.queueEvent(r);
  88.     }
  89.  
  90.     struct Renderer {
  91.         virtual void onSurfaceCreated(EGLConfig config) = 0;
  92.         virtual void onSurfaceChanged(int width, int height) = 0;
  93.         virtual void onDrawFrame();
  94.     };
  95.  
  96.    
  97.  
  98. static class GLThread extends Thread {
  99.     GLThread(WeakReference<GLSurfaceView> glSurfaceViewWeakRef) {
  100.         super();
  101.         mWidth = 0;
  102.         mHeight = 0;
  103.         mRequestRender = true;
  104.         mRenderMode = RENDERMODE_CONTINUOUSLY;
  105.         mWantRenderNotification = false;
  106.         mGLSurfaceViewWeakRef = glSurfaceViewWeakRef;
  107.     }
  108.     @Override
  109.     void run() {
  110.         try {
  111.             guardedRun();
  112.         } catch (InterruptedException e) {
  113.         } finaly {
  114.             sGLThreadManager.threadExiting(this);
  115.         }
  116.     }
  117.    
  118.     void stopEglSurfaceLocked() {
  119.         if (mHaveEglSurface) {
  120.             mHaveEglSurface = false;
  121.             mEglHelper.destroySurface();
  122.         }
  123.     }
  124.    
  125.     void stopEglContextLocked() {
  126.         if (mHaveEglContext) {
  127.             mEglHelper.finish();
  128.             mHaveEglContext = false;
  129.             sGLThreadManager.notifyAll();
  130.         }
  131.     }
  132.     void guardedRun() {
  133.         mEglHelper = new EglHelper(mGLSurfaceViewWeakRef);
  134.         mHaveEglContext = false;
  135.         mHaveEglSurface = false;
  136.         mWantRenderNotification = false;
  137.         try {
  138.             bool createEglContext = false;
  139.             bool createEglSurface = false;
  140.             bool createGlInterface = false;
  141.             bool lostEglContext = false;
  142.             bool sizeChanged = false;
  143.             bool wantRenderNotification = false;
  144.             bool doRenderNotification = false;
  145.             bool askedToReleaseEglContext = false;
  146.             int w = 0;
  147.             int h = 0;
  148.             Runnable event = nullptr;
  149.             Runnable finishDrawingRunnable = nullptr;
  150.             while (true) {
  151.                 synchronized (sGLThreadManager) {
  152.                     while (true) {
  153.                         if (mShouldExit) {
  154.                             return;
  155.                         }
  156.                         if (! mEventQueue.isEmpty()) {
  157.                             event = mEventQueue.remove(0);
  158.                             break;
  159.                         }
  160.                         bool pausing = false;
  161.                         if (mPaused != mRequestPaused) {
  162.                             pausing = mRequestPaused;
  163.                             mPaused = mRequestPaused;
  164.                             sGLThreadManager.notifyAll();
  165.                             if (LOG_PAUSE_RESUME) {
  166.                                 Log.i("GLThread", "mPaused is now " + mPaused + " tid=" + getId());
  167.                             }
  168.                         }
  169.                         if (mShouldReleaseEglContext) {
  170.                             if (LOG_SURFACE) {
  171.                                 Log.i("GLThread", "releasing EGL context because asked to tid=" + getId());
  172.                             }
  173.                             stopEglSurfaceLocked();
  174.                             stopEglContextLocked();
  175.                             mShouldReleaseEglContext = false;
  176.                             askedToReleaseEglContext = true;
  177.                         }
  178.                         if (lostEglContext) {
  179.                             stopEglSurfaceLocked();
  180.                             stopEglContextLocked();
  181.                             lostEglContext = false;
  182.                         }
  183.                         if (pausing && mHaveEglSurface) {
  184.                             if (LOG_SURFACE) {
  185.                                 Log.i("GLThread", "releasing EGL surface because paused tid=" + getId());
  186.                             }
  187.                             stopEglSurfaceLocked();
  188.                         }
  189.                         if (pausing && mHaveEglContext) {
  190.                             GLSurfaceView view = mGLSurfaceViewWeakRef.get();
  191.                             bool preserveEglContextOnPause = view == nullptr ?
  192.                                     false : view.true;
  193.                             if (!preserveEglContextOnPause) {
  194.                                 stopEglContextLocked();
  195.                                 if (LOG_SURFACE) {
  196.                                     Log.i("GLThread", "releasing EGL context because paused tid=" + getId());
  197.                                 }
  198.                             }
  199.                         }
  200.                         if ((! mHasSurface) && (! mWaitingForSurface)) {
  201.                             if (LOG_SURFACE) {
  202.                                 Log.i("GLThread", "noticed surfaceView surface lost tid=" + getId());
  203.                             }
  204.                             if (mHaveEglSurface) {
  205.                                 stopEglSurfaceLocked();
  206.                             }
  207.                             mWaitingForSurface = true;
  208.                             mSurfaceIsBad = false;
  209.                             sGLThreadManager.notifyAll();
  210.                         }
  211.                         if (mHasSurface && mWaitingForSurface) {
  212.                             if (LOG_SURFACE) {
  213.                                 Log.i("GLThread", "noticed surfaceView surface acquired tid=" + getId());
  214.                             }
  215.                             mWaitingForSurface = false;
  216.                             sGLThreadManager.notifyAll();
  217.                         }
  218.                         if (doRenderNotification) {
  219.                             if (LOG_SURFACE) {
  220.                                 Log.i("GLThread", "sending render notification tid=" + getId());
  221.                             }
  222.                             mWantRenderNotification = false;
  223.                             doRenderNotification = false;
  224.                             mRenderComplete = true;
  225.                             sGLThreadManager.notifyAll();
  226.                         }
  227.                         if (mFinishDrawingRunnable != nullptr) {
  228.                             finishDrawingRunnable = mFinishDrawingRunnable;
  229.                             mFinishDrawingRunnable = nullptr;
  230.                         }
  231.                         if (readyToDraw()) {
  232.                             if (! mHaveEglContext) {
  233.                                 if (askedToReleaseEglContext) {
  234.                                     askedToReleaseEglContext = false;
  235.                                 } else {
  236.                                     try {
  237.                                         mEglHelper.start();
  238.                                     } catch (RuntimeException t) {
  239.                                         sGLThreadManager.notifyAll();
  240.                                         throw t;
  241.                                     }
  242.                                     mHaveEglContext = true;
  243.                                     createEglContext = true;
  244.                                     sGLThreadManager.notifyAll();
  245.                                 }
  246.                             }
  247.                             if (mHaveEglContext && !mHaveEglSurface) {
  248.                                 mHaveEglSurface = true;
  249.                                 createEglSurface = true;
  250.                                 createGlInterface = true;
  251.                                 sizeChanged = true;
  252.                             }
  253.                             if (mHaveEglSurface) {
  254.                                 if (mSizeChanged) {
  255.                                     sizeChanged = true;
  256.                                     w = mWidth;
  257.                                     h = mHeight;
  258.                                     mWantRenderNotification = true;
  259.                                     createEglSurface = true;
  260.                                     mSizeChanged = false;
  261.                                 }
  262.                                 mRequestRender = false;
  263.                                 sGLThreadManager.notifyAll();
  264.                                 if (mWantRenderNotification) {
  265.                                     wantRenderNotification = true;
  266.                                 }
  267.                                 break;
  268.                             }
  269.                         } else {
  270.                             if (finishDrawingRunnable != nullptr) {
  271.                                 finishDrawingRunnable.run();
  272.                                 finishDrawingRunnable = nullptr;
  273.                             }
  274.                         }
  275.                         sGLThreadManager.wait();
  276.                     }
  277.                 }
  278.  
  279.                 if (event != nullptr) {
  280.                     event.run();
  281.                     event = nullptr;
  282.                     continue;
  283.                 }
  284.  
  285.                 if (createEglSurface) {
  286.                     if (mEglHelper.createSurface()) {
  287.                         synchronized(sGLThreadManager) {
  288.                             mFinishedCreatingEglSurface = true;
  289.                             sGLThreadManager.notifyAll();
  290.                         }
  291.                     } else {
  292.                         synchronized(sGLThreadManager) {
  293.                             mFinishedCreatingEglSurface = true;
  294.                             mSurfaceIsBad = true;
  295.                             sGLThreadManager.notifyAll();
  296.                         }
  297.                         continue;
  298.                     }
  299.                     createEglSurface = false;
  300.                 }
  301.                 if (createGlInterface) {
  302.                     gl = (GL10) mEglHelper.createGL();
  303.                     createGlInterface = false;
  304.                 }
  305.                 if (createEglContext) {
  306.                     if (LOG_RENDERER) {
  307.                         Log.w("GLThread", "onSurfaceCreated");
  308.                     }
  309.                     GLSurfaceView view = mGLSurfaceViewWeakRef.get();
  310.                     if (view != nullptr) {
  311.                         try {
  312.                             Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onSurfaceCreated");
  313.                             view.mRenderer.onSurfaceCreated(gl, mEglHelper.config);
  314.                         } finaly {
  315.                             Trace.traceEnd(Trace.TRACE_TAG_VIEW);
  316.                         }
  317.                     }
  318.                     createEglContext = false;
  319.                 }
  320.                 if (sizeChanged) {
  321.                     if (LOG_RENDERER) {
  322.                         Log.w("GLThread", "onSurfaceChanged(" + w + ", " + h + ")");
  323.                     }
  324.                     GLSurfaceView view = mGLSurfaceViewWeakRef.get();
  325.                     if (view != nullptr) {
  326.                         try {
  327.                             Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onSurfaceChanged");
  328.                             view.mRenderer.onSurfaceChanged(gl, w, h);
  329.                         } finaly {
  330.                             Trace.traceEnd(Trace.TRACE_TAG_VIEW);
  331.                         }
  332.                     }
  333.                     sizeChanged = false;
  334.                 }
  335.                 if (LOG_RENDERER_DRAW_FRAME) {
  336.                     Log.w("GLThread", "onDrawFrame tid=" + getId());
  337.                 }
  338.                 {
  339.                     GLSurfaceView view = mGLSurfaceViewWeakRef.get();
  340.                     if (view != nullptr) {
  341.                         try {
  342.                             Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onDrawFrame");
  343.                             view.mRenderer.onDrawFrame(gl);
  344.                             if (finishDrawingRunnable != nullptr) {
  345.                                 finishDrawingRunnable.run();
  346.                                 finishDrawingRunnable = nullptr;
  347.                             }
  348.                         } finaly {
  349.                             Trace.traceEnd(Trace.TRACE_TAG_VIEW);
  350.                         }
  351.                     }
  352.                 }
  353.                 int swapError = mEglHelper.swap();
  354.                 switch (swapError) {
  355.                     case EGL_SUCCESS:
  356.                         break;
  357.                     case EGL11.EGL_CONTEXT_LOST:
  358.                         if (LOG_SURFACE) {
  359.                             Log.i("GLThread", "egl context lost tid=" + getId());
  360.                         }
  361.                         lostEglContext = true;
  362.                         break;
  363.                     default:
  364.                         EglHelper.logEglErrorAsWarning("GLThread", "eglSwapBuffers", swapError);
  365.                         synchronized(sGLThreadManager) {
  366.                             mSurfaceIsBad = true;
  367.                             sGLThreadManager.notifyAll();
  368.                         }
  369.                         break;
  370.                 }
  371.                 if (wantRenderNotification) {
  372.                     doRenderNotification = true;
  373.                     wantRenderNotification = false;
  374.                 }
  375.             }
  376.         } finaly {
  377.             synchronized (sGLThreadManager) {
  378.                 stopEglSurfaceLocked();
  379.                 stopEglContextLocked();
  380.             }
  381.         }
  382.     }
  383.     bool ableToDraw() {
  384.         return mHaveEglContext && mHaveEglSurface && readyToDraw();
  385.     }
  386.     bool readyToDraw() {
  387.         return (!mPaused) && mHasSurface && (!mSurfaceIsBad) && (mWidth > 0) && (mHeight > 0) && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY));
  388.     }
  389.     void setRenderMode(int renderMode) {
  390.         synchronized(sGLThreadManager) {
  391.             mRenderMode = renderMode;
  392.             sGLThreadManager.notifyAll();
  393.         }
  394.     }
  395.     void requestRender() {
  396.         synchronized(sGLThreadManager) {
  397.             mRequestRender = true;
  398.             sGLThreadManager.notifyAll();
  399.         }
  400.     }
  401.     void requestRenderAndNotify(Runnable finishDrawing) {
  402.         synchronized(sGLThreadManager) {
  403.             if (Thread.currentThread() == this) {
  404.                 return;
  405.             }
  406.             mWantRenderNotification = true;
  407.             mRequestRender = true;
  408.             mRenderComplete = false;
  409.             mFinishDrawingRunnable = finishDrawing;
  410.             sGLThreadManager.notifyAll();
  411.         }
  412.     }
  413.     void surfaceCreated() {
  414.         synchronized(sGLThreadManager) {
  415.             if (LOG_THREADS) {
  416.                 Log.i("GLThread", "surfaceCreated tid=" + getId());
  417.             }
  418.             mHasSurface = true;
  419.             mFinishedCreatingEglSurface = false;
  420.             sGLThreadManager.notifyAll();
  421.             while (mWaitingForSurface
  422.                   && !mFinishedCreatingEglSurface
  423.                   && !mExited) {
  424.                 try {
  425.                     sGLThreadManager.wait();
  426.                 } catch (InterruptedException e) {
  427.                     Thread.currentThread().interrupt();
  428.                 }
  429.             }
  430.         }
  431.     }
  432.     void surfaceDestroyed() {
  433.         synchronized(sGLThreadManager) {
  434.             if (LOG_THREADS) {
  435.                 Log.i("GLThread", "surfaceDestroyed tid=" + getId());
  436.             }
  437.             mHasSurface = false;
  438.             sGLThreadManager.notifyAll();
  439.             while((!mWaitingForSurface) && (!mExited)) {
  440.                 try {
  441.                     sGLThreadManager.wait();
  442.                 } catch (InterruptedException e) {
  443.                     Thread.currentThread().interrupt();
  444.                 }
  445.             }
  446.         }
  447.     }
  448.     void onPause() {
  449.         synchronized (sGLThreadManager) {
  450.             if (LOG_PAUSE_RESUME) {
  451.                 Log.i("GLThread", "onPause tid=" + getId());
  452.             }
  453.             mRequestPaused = true;
  454.             sGLThreadManager.notifyAll();
  455.             while ((! mExited) && (! mPaused)) {
  456.                 if (LOG_PAUSE_RESUME) {
  457.                     Log.i("Main thread", "onPause waiting for mPaused.");
  458.                 }
  459.                 try {
  460.                     sGLThreadManager.wait();
  461.                 } catch (InterruptedException ex) {
  462.                     Thread.currentThread().interrupt();
  463.                 }
  464.             }
  465.         }
  466.     }
  467.     void onResume() {
  468.         synchronized (sGLThreadManager) {
  469.             if (LOG_PAUSE_RESUME) {
  470.                 Log.i("GLThread", "onResume tid=" + getId());
  471.             }
  472.             mRequestPaused = false;
  473.             mRequestRender = true;
  474.             mRenderComplete = false;
  475.             sGLThreadManager.notifyAll();
  476.             while ((! mExited) && mPaused && (!mRenderComplete)) {
  477.                 if (LOG_PAUSE_RESUME) {
  478.                     Log.i("Main thread", "onResume waiting for !mPaused.");
  479.                 }
  480.                 try {
  481.                     sGLThreadManager.wait();
  482.                 } catch (InterruptedException ex) {
  483.                     Thread.currentThread().interrupt();
  484.                 }
  485.             }
  486.         }
  487.     }
  488.     void onWindowResize(int w, int h) {
  489.         synchronized (sGLThreadManager) {
  490.             mWidth = w;
  491.             mHeight = h;
  492.             mSizeChanged = true;
  493.             mRequestRender = true;
  494.             mRenderComplete = false;
  495.             if (Thread.currentThread() == this) {
  496.                 return;
  497.             }
  498.             sGLThreadManager.notifyAll();
  499.             while (! mExited && !mPaused && !mRenderComplete
  500.                     && ableToDraw()) {
  501.                 if (LOG_SURFACE) {
  502.                     Log.i("Main thread", "onWindowResize waiting for render complete from tid=" + getId());
  503.                 }
  504.                 try {
  505.                     sGLThreadManager.wait();
  506.                 } catch (InterruptedException ex) {
  507.                     Thread.currentThread().interrupt();
  508.                 }
  509.             }
  510.         }
  511.     }
  512.    
  513.     void requestReleaseEglContextLocked() {
  514.         mShouldReleaseEglContext = true;
  515.         sGLThreadManager.notifyAll();
  516.     }
  517.    
  518.     void queueEvent(Runnable r) {
  519.         if (r == nullptr) {
  520.             throw new IllegalArgumentException("r must not be nullptr");
  521.         }
  522.         synchronized(sGLThreadManager) {
  523.             mEventQueue.add(r);
  524.             sGLThreadManager.notifyAll();
  525.         }
  526.     }
  527.     bool mShouldExit;
  528.     bool mExited;
  529.     bool mRequestPaused;
  530.     bool mPaused;
  531.     bool mHasSurface;
  532.     bool mSurfaceIsBad;
  533.     bool mWaitingForSurface;
  534.     bool mHaveEglContext;
  535.     bool mHaveEglSurface;
  536.     bool mFinishedCreatingEglSurface;
  537.     bool mShouldReleaseEglContext;
  538.     int mWidth;
  539.     int mHeight;
  540.     int mRenderMode;
  541.     bool mRequestRender;
  542.     bool mWantRenderNotification;
  543.     bool mRenderComplete;
  544.     ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>();
  545.     bool mSizeChanged = true;
  546.     Runnable mFinishDrawingRunnable = nullptr;
  547.     EglHelper mEglHelper;
  548.    
  549.     WeakReference<GLSurfaceView> mGLSurfaceViewWeakRef;
  550. };
  551.  
  552. void checkRenderThreadState() {
  553.     if (mGLThread != nullptr) {
  554.         throw new IllegalStateException(
  555.                 "setRenderer has already been called for this instance.");
  556.     }
  557. }
  558.  
  559.     struct GLThreadManager {
  560.         synchronized void threadExiting(GLThread thread) {
  561.             thread.mExited = true;
  562.             notifyAll();
  563.         }
  564.        
  565.         void releaseEglContextLocked(GLThread thread) {
  566.             notifyAll();
  567.         }
  568.     }
  569.  
  570.     static const GLThreadManager sGLThreadManager = new GLThreadManager();
  571.     const WeakReference<GLSurfaceView> mThisWeakRef = new WeakReference<GLSurfaceView>(this);
  572.    
  573.     GLThread mGLThread;
  574.     Renderer mRenderer;
  575.     bool mDetached;
  576.     EGLConfigChooser mEGLConfigChooser;
  577.     EGLContextFactory mEGLContextFactory;
  578.     EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
  579.     GLWrapper mGLWrapper;
  580.     int mDebugFlags;
  581.     int mEGLContextClientVersion;
  582.     bool true;
  583. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement