GLWindowContext_android.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright 2016 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include <EGL/egl.h>
  8. #include <GLES/gl.h>
  9. #include "include/gpu/gl/GrGLInterface.h"
  10. #include "tools/sk_app/GLWindowContext.h"
  11. #include "tools/sk_app/android/WindowContextFactory_android.h"
  12. using sk_app::GLWindowContext;
  13. using sk_app::DisplayParams;
  14. namespace {
  15. class GLWindowContext_android : public GLWindowContext {
  16. public:
  17. GLWindowContext_android(ANativeWindow*, const DisplayParams&);
  18. ~GLWindowContext_android() override;
  19. void onSwapBuffers() override;
  20. sk_sp<const GrGLInterface> onInitializeContext() override;
  21. void onDestroyContext() override;
  22. private:
  23. EGLDisplay fDisplay;
  24. EGLContext fEGLContext;
  25. EGLSurface fSurfaceAndroid;
  26. // For setDisplayParams and resize which call onInitializeContext with null platformData
  27. ANativeWindow* fNativeWindow = nullptr;
  28. typedef GLWindowContext INHERITED;
  29. };
  30. GLWindowContext_android::GLWindowContext_android(ANativeWindow* window,
  31. const DisplayParams& params)
  32. : INHERITED(params)
  33. , fDisplay(EGL_NO_DISPLAY)
  34. , fEGLContext(EGL_NO_CONTEXT)
  35. , fSurfaceAndroid(EGL_NO_SURFACE)
  36. , fNativeWindow(window) {
  37. // any config code here (particularly for msaa)?
  38. this->initializeContext();
  39. }
  40. GLWindowContext_android::~GLWindowContext_android() {
  41. this->destroyContext();
  42. }
  43. sk_sp<const GrGLInterface> GLWindowContext_android::onInitializeContext() {
  44. fWidth = ANativeWindow_getWidth(fNativeWindow);
  45. fHeight = ANativeWindow_getHeight(fNativeWindow);
  46. fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  47. EGLint majorVersion;
  48. EGLint minorVersion;
  49. eglInitialize(fDisplay, &majorVersion, &minorVersion);
  50. SkAssertResult(eglBindAPI(EGL_OPENGL_ES_API));
  51. EGLint numConfigs = 0;
  52. EGLint eglSampleCnt = fDisplayParams.fMSAASampleCount > 1 ? fDisplayParams.fMSAASampleCount > 1
  53. : 0;
  54. const EGLint configAttribs[] = {
  55. EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
  56. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  57. EGL_RED_SIZE, 8,
  58. EGL_GREEN_SIZE, 8,
  59. EGL_BLUE_SIZE, 8,
  60. EGL_ALPHA_SIZE, 8,
  61. EGL_STENCIL_SIZE, 8,
  62. EGL_SAMPLE_BUFFERS, eglSampleCnt ? 1 : 0,
  63. EGL_SAMPLES, eglSampleCnt,
  64. EGL_NONE
  65. };
  66. EGLConfig surfaceConfig;
  67. SkAssertResult(eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs));
  68. SkASSERT(numConfigs > 0);
  69. static const EGLint kEGLContextAttribsForOpenGLES[] = {
  70. EGL_CONTEXT_CLIENT_VERSION, 2,
  71. EGL_NONE
  72. };
  73. fEGLContext = eglCreateContext(
  74. fDisplay, surfaceConfig, nullptr, kEGLContextAttribsForOpenGLES);
  75. SkASSERT(EGL_NO_CONTEXT != fEGLContext);
  76. // SkDebugf("EGL: %d.%d", majorVersion, minorVersion);
  77. // SkDebugf("Vendor: %s", eglQueryString(fDisplay, EGL_VENDOR));
  78. // SkDebugf("Extensions: %s", eglQueryString(fDisplay, EGL_EXTENSIONS));
  79. fSurfaceAndroid = eglCreateWindowSurface(fDisplay, surfaceConfig, fNativeWindow, nullptr);
  80. SkASSERT(EGL_NO_SURFACE != fSurfaceAndroid);
  81. SkAssertResult(eglMakeCurrent(fDisplay, fSurfaceAndroid, fSurfaceAndroid, fEGLContext));
  82. // GLWindowContext::initializeContext will call GrGLMakeNativeInterface so we
  83. // won't call it here.
  84. glClearStencil(0);
  85. glClearColor(0, 0, 0, 0);
  86. glStencilMask(0xffffffff);
  87. glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  88. eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_STENCIL_SIZE, &fStencilBits);
  89. eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_SAMPLES, &fSampleCount);
  90. fSampleCount = SkTMax(fSampleCount, 1);
  91. eglSwapInterval(fDisplay, fDisplayParams.fDisableVsync ? 0 : 1);
  92. return GrGLMakeNativeInterface();
  93. }
  94. void GLWindowContext_android::onDestroyContext() {
  95. if (!fDisplay || !fEGLContext || !fSurfaceAndroid) {
  96. return;
  97. }
  98. eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  99. SkAssertResult(eglDestroySurface(fDisplay, fSurfaceAndroid));
  100. SkAssertResult(eglDestroyContext(fDisplay, fEGLContext));
  101. fEGLContext = EGL_NO_CONTEXT;
  102. fSurfaceAndroid = EGL_NO_SURFACE;
  103. }
  104. void GLWindowContext_android::onSwapBuffers() {
  105. if (fDisplay && fEGLContext && fSurfaceAndroid) {
  106. eglSwapBuffers(fDisplay, fSurfaceAndroid);
  107. }
  108. }
  109. } // anonymous namespace
  110. namespace sk_app {
  111. namespace window_context_factory {
  112. WindowContext* NewGLForAndroid(ANativeWindow* window, const DisplayParams& params) {
  113. WindowContext* ctx = new GLWindowContext_android(window, params);
  114. if (!ctx->isValid()) {
  115. delete ctx;
  116. return nullptr;
  117. }
  118. return ctx;
  119. }
  120. } // namespace window_context_factory
  121. } // namespace sk_app