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