rsdFrameBufferObj.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (C) 2011 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "rsdFrameBufferObj.h"
  17. #include "rsdAllocation.h"
  18. #include "rsdGL.h"
  19. #include "rsdCore.h"
  20. #include <GLES2/gl2.h>
  21. #include <GLES2/gl2ext.h>
  22. using android::renderscript::Context;
  23. RsdFrameBufferObj::RsdFrameBufferObj() {
  24. mFBOId = 0;
  25. mWidth = 0;
  26. mHeight = 0;
  27. mColorTargetsCount = 1;
  28. mColorTargets = new DrvAllocation*[mColorTargetsCount];
  29. for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
  30. mColorTargets[i] = 0;
  31. }
  32. mDepthTarget = nullptr;
  33. mDirty = true;
  34. }
  35. RsdFrameBufferObj::~RsdFrameBufferObj() {
  36. if(mFBOId != 0) {
  37. glDeleteFramebuffers(1, &mFBOId);
  38. }
  39. delete [] mColorTargets;
  40. }
  41. void RsdFrameBufferObj::checkError(const Context *rsc) {
  42. GLenum status;
  43. status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  44. switch (status) {
  45. case GL_FRAMEBUFFER_COMPLETE:
  46. break;
  47. case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
  48. rsc->setError(RS_ERROR_BAD_VALUE,
  49. "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT");
  50. break;
  51. case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
  52. rsc->setError(RS_ERROR_BAD_VALUE,
  53. "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
  54. break;
  55. case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
  56. rsc->setError(RS_ERROR_BAD_VALUE,
  57. "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
  58. break;
  59. case GL_FRAMEBUFFER_UNSUPPORTED:
  60. rsc->setError(RS_ERROR_BAD_VALUE,
  61. "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED");
  62. break;
  63. }
  64. }
  65. void RsdFrameBufferObj::setDepthAttachment() {
  66. if (mDepthTarget != nullptr) {
  67. if (mDepthTarget->textureID) {
  68. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
  69. GL_TEXTURE_2D, mDepthTarget->textureID, 0);
  70. } else {
  71. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
  72. GL_RENDERBUFFER, mDepthTarget->renderTargetID);
  73. }
  74. } else {
  75. // Reset last attachment
  76. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
  77. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
  78. }
  79. }
  80. void RsdFrameBufferObj::setColorAttachment() {
  81. // Now attach color targets
  82. for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
  83. if (mColorTargets[i] != nullptr) {
  84. if (mColorTargets[i]->textureID) {
  85. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
  86. GL_TEXTURE_2D, mColorTargets[i]->textureID, 0);
  87. } else {
  88. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
  89. GL_RENDERBUFFER, mColorTargets[i]->renderTargetID);
  90. }
  91. } else {
  92. // Reset last attachment
  93. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
  94. GL_RENDERBUFFER, 0);
  95. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
  96. GL_TEXTURE_2D, 0, 0);
  97. }
  98. }
  99. }
  100. bool RsdFrameBufferObj::renderToFramebuffer() {
  101. if (mDepthTarget != nullptr) {
  102. return false;
  103. }
  104. for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
  105. if (mColorTargets[i] != nullptr) {
  106. return false;
  107. }
  108. }
  109. return true;
  110. }
  111. void RsdFrameBufferObj::setActive(const Context *rsc) {
  112. RsdHal *dc = (RsdHal *)rsc->mHal.drv;
  113. bool framebuffer = renderToFramebuffer();
  114. if(mColorTargets[0] && mColorTargets[0]->wnd) {
  115. rsdGLSetInternalSurface(rsc, mColorTargets[0]->wnd);
  116. EGLint width, height;
  117. eglQuerySurface(dc->gl.egl.display, dc->gl.egl.surface, EGL_WIDTH, &width);
  118. eglQuerySurface(dc->gl.egl.display, dc->gl.egl.surface, EGL_HEIGHT, &height);
  119. RSD_CALL_GL(glViewport, 0, 0, width, height);
  120. } else {
  121. if (!framebuffer) {
  122. if(mFBOId == 0) {
  123. RSD_CALL_GL(glGenFramebuffers, 1, &mFBOId);
  124. }
  125. RSD_CALL_GL(glBindFramebuffer, GL_FRAMEBUFFER, mFBOId);
  126. if (mDirty) {
  127. setDepthAttachment();
  128. setColorAttachment();
  129. mDirty = false;
  130. }
  131. RSD_CALL_GL(glViewport, 0, 0, mWidth, mHeight);
  132. checkError(rsc);
  133. } else {
  134. if(dc->gl.wndSurface != dc->gl.currentWndSurface) {
  135. rsdGLSetInternalSurface(rsc, dc->gl.wndSurface);
  136. } else {
  137. RSD_CALL_GL(glBindFramebuffer, GL_FRAMEBUFFER, 0);
  138. }
  139. RSD_CALL_GL(glViewport, 0, 0, rsc->getWidth(), rsc->getHeight());
  140. }
  141. }
  142. }