1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #include "GLHelper.h"
18*38e8c45fSAndroid Build Coastguard Worker
19*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2ext.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_libgui_flags.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <gui/SurfaceComposerClient.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayMode.h>
24*38e8c45fSAndroid Build Coastguard Worker
25*38e8c45fSAndroid Build Coastguard Worker namespace android {
26*38e8c45fSAndroid Build Coastguard Worker
GLHelper()27*38e8c45fSAndroid Build Coastguard Worker GLHelper::GLHelper() :
28*38e8c45fSAndroid Build Coastguard Worker mDisplay(EGL_NO_DISPLAY),
29*38e8c45fSAndroid Build Coastguard Worker mContext(EGL_NO_CONTEXT),
30*38e8c45fSAndroid Build Coastguard Worker mDummySurface(EGL_NO_SURFACE),
31*38e8c45fSAndroid Build Coastguard Worker mConfig(0),
32*38e8c45fSAndroid Build Coastguard Worker mShaderPrograms(nullptr),
33*38e8c45fSAndroid Build Coastguard Worker mDitherTexture(0) {
34*38e8c45fSAndroid Build Coastguard Worker }
35*38e8c45fSAndroid Build Coastguard Worker
~GLHelper()36*38e8c45fSAndroid Build Coastguard Worker GLHelper::~GLHelper() {
37*38e8c45fSAndroid Build Coastguard Worker }
38*38e8c45fSAndroid Build Coastguard Worker
setUp(const sp<IBinder> & displayToken,const ShaderDesc * shaderDescs,size_t numShaders)39*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::setUp(const sp<IBinder>& displayToken, const ShaderDesc* shaderDescs,
40*38e8c45fSAndroid Build Coastguard Worker size_t numShaders) {
41*38e8c45fSAndroid Build Coastguard Worker bool result;
42*38e8c45fSAndroid Build Coastguard Worker
43*38e8c45fSAndroid Build Coastguard Worker mDisplayToken = displayToken;
44*38e8c45fSAndroid Build Coastguard Worker
45*38e8c45fSAndroid Build Coastguard Worker mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
46*38e8c45fSAndroid Build Coastguard Worker if (mDisplay == EGL_NO_DISPLAY) {
47*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "eglGetDisplay error: %#x\n", eglGetError());
48*38e8c45fSAndroid Build Coastguard Worker return false;
49*38e8c45fSAndroid Build Coastguard Worker }
50*38e8c45fSAndroid Build Coastguard Worker
51*38e8c45fSAndroid Build Coastguard Worker EGLint majorVersion;
52*38e8c45fSAndroid Build Coastguard Worker EGLint minorVersion;
53*38e8c45fSAndroid Build Coastguard Worker result = eglInitialize(mDisplay, &majorVersion, &minorVersion);
54*38e8c45fSAndroid Build Coastguard Worker if (result != EGL_TRUE) {
55*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "eglInitialize error: %#x\n", eglGetError());
56*38e8c45fSAndroid Build Coastguard Worker return false;
57*38e8c45fSAndroid Build Coastguard Worker }
58*38e8c45fSAndroid Build Coastguard Worker
59*38e8c45fSAndroid Build Coastguard Worker EGLint numConfigs = 0;
60*38e8c45fSAndroid Build Coastguard Worker EGLint configAttribs[] = {
61*38e8c45fSAndroid Build Coastguard Worker EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
62*38e8c45fSAndroid Build Coastguard Worker EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
63*38e8c45fSAndroid Build Coastguard Worker EGL_RED_SIZE, 8,
64*38e8c45fSAndroid Build Coastguard Worker EGL_GREEN_SIZE, 8,
65*38e8c45fSAndroid Build Coastguard Worker EGL_BLUE_SIZE, 8,
66*38e8c45fSAndroid Build Coastguard Worker EGL_ALPHA_SIZE, 8,
67*38e8c45fSAndroid Build Coastguard Worker EGL_NONE
68*38e8c45fSAndroid Build Coastguard Worker };
69*38e8c45fSAndroid Build Coastguard Worker result = eglChooseConfig(mDisplay, configAttribs, &mConfig, 1,
70*38e8c45fSAndroid Build Coastguard Worker &numConfigs);
71*38e8c45fSAndroid Build Coastguard Worker if (result != EGL_TRUE) {
72*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "eglChooseConfig error: %#x\n", eglGetError());
73*38e8c45fSAndroid Build Coastguard Worker return false;
74*38e8c45fSAndroid Build Coastguard Worker }
75*38e8c45fSAndroid Build Coastguard Worker
76*38e8c45fSAndroid Build Coastguard Worker EGLint contextAttribs[] = {
77*38e8c45fSAndroid Build Coastguard Worker EGL_CONTEXT_CLIENT_VERSION, 2,
78*38e8c45fSAndroid Build Coastguard Worker EGL_NONE
79*38e8c45fSAndroid Build Coastguard Worker };
80*38e8c45fSAndroid Build Coastguard Worker mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT,
81*38e8c45fSAndroid Build Coastguard Worker contextAttribs);
82*38e8c45fSAndroid Build Coastguard Worker if (mContext == EGL_NO_CONTEXT) {
83*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "eglCreateContext error: %#x\n", eglGetError());
84*38e8c45fSAndroid Build Coastguard Worker return false;
85*38e8c45fSAndroid Build Coastguard Worker }
86*38e8c45fSAndroid Build Coastguard Worker
87*38e8c45fSAndroid Build Coastguard Worker bool resultb = createNamedSurfaceTexture(0, 1, 1, &mDummyGLConsumer,
88*38e8c45fSAndroid Build Coastguard Worker &mDummySurface);
89*38e8c45fSAndroid Build Coastguard Worker if (!resultb) {
90*38e8c45fSAndroid Build Coastguard Worker return false;
91*38e8c45fSAndroid Build Coastguard Worker }
92*38e8c45fSAndroid Build Coastguard Worker
93*38e8c45fSAndroid Build Coastguard Worker resultb = makeCurrent(mDummySurface);
94*38e8c45fSAndroid Build Coastguard Worker if (!resultb) {
95*38e8c45fSAndroid Build Coastguard Worker return false;
96*38e8c45fSAndroid Build Coastguard Worker }
97*38e8c45fSAndroid Build Coastguard Worker
98*38e8c45fSAndroid Build Coastguard Worker resultb = setUpShaders(shaderDescs, numShaders);
99*38e8c45fSAndroid Build Coastguard Worker if (!resultb) {
100*38e8c45fSAndroid Build Coastguard Worker return false;
101*38e8c45fSAndroid Build Coastguard Worker }
102*38e8c45fSAndroid Build Coastguard Worker
103*38e8c45fSAndroid Build Coastguard Worker return true;
104*38e8c45fSAndroid Build Coastguard Worker }
105*38e8c45fSAndroid Build Coastguard Worker
tearDown()106*38e8c45fSAndroid Build Coastguard Worker void GLHelper::tearDown() {
107*38e8c45fSAndroid Build Coastguard Worker if (mShaderPrograms != nullptr) {
108*38e8c45fSAndroid Build Coastguard Worker delete[] mShaderPrograms;
109*38e8c45fSAndroid Build Coastguard Worker mShaderPrograms = nullptr;
110*38e8c45fSAndroid Build Coastguard Worker }
111*38e8c45fSAndroid Build Coastguard Worker
112*38e8c45fSAndroid Build Coastguard Worker if (mSurfaceComposerClient != nullptr) {
113*38e8c45fSAndroid Build Coastguard Worker mSurfaceComposerClient->dispose();
114*38e8c45fSAndroid Build Coastguard Worker mSurfaceComposerClient.clear();
115*38e8c45fSAndroid Build Coastguard Worker }
116*38e8c45fSAndroid Build Coastguard Worker
117*38e8c45fSAndroid Build Coastguard Worker if (mDisplay != EGL_NO_DISPLAY) {
118*38e8c45fSAndroid Build Coastguard Worker eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
119*38e8c45fSAndroid Build Coastguard Worker EGL_NO_CONTEXT);
120*38e8c45fSAndroid Build Coastguard Worker }
121*38e8c45fSAndroid Build Coastguard Worker
122*38e8c45fSAndroid Build Coastguard Worker if (mContext != EGL_NO_CONTEXT) {
123*38e8c45fSAndroid Build Coastguard Worker eglDestroyContext(mDisplay, mContext);
124*38e8c45fSAndroid Build Coastguard Worker }
125*38e8c45fSAndroid Build Coastguard Worker
126*38e8c45fSAndroid Build Coastguard Worker if (mDummySurface != EGL_NO_SURFACE) {
127*38e8c45fSAndroid Build Coastguard Worker eglDestroySurface(mDisplay, mDummySurface);
128*38e8c45fSAndroid Build Coastguard Worker }
129*38e8c45fSAndroid Build Coastguard Worker
130*38e8c45fSAndroid Build Coastguard Worker mDisplay = EGL_NO_DISPLAY;
131*38e8c45fSAndroid Build Coastguard Worker mContext = EGL_NO_CONTEXT;
132*38e8c45fSAndroid Build Coastguard Worker mDummySurface = EGL_NO_SURFACE;
133*38e8c45fSAndroid Build Coastguard Worker mDummyGLConsumer.clear();
134*38e8c45fSAndroid Build Coastguard Worker mConfig = 0;
135*38e8c45fSAndroid Build Coastguard Worker }
136*38e8c45fSAndroid Build Coastguard Worker
makeCurrent(EGLSurface surface)137*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::makeCurrent(EGLSurface surface) {
138*38e8c45fSAndroid Build Coastguard Worker EGLint result;
139*38e8c45fSAndroid Build Coastguard Worker
140*38e8c45fSAndroid Build Coastguard Worker result = eglMakeCurrent(mDisplay, surface, surface, mContext);
141*38e8c45fSAndroid Build Coastguard Worker if (result != EGL_TRUE) {
142*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "eglMakeCurrent error: %#x\n", eglGetError());
143*38e8c45fSAndroid Build Coastguard Worker return false;
144*38e8c45fSAndroid Build Coastguard Worker }
145*38e8c45fSAndroid Build Coastguard Worker
146*38e8c45fSAndroid Build Coastguard Worker EGLint w, h;
147*38e8c45fSAndroid Build Coastguard Worker eglQuerySurface(mDisplay, surface, EGL_WIDTH, &w);
148*38e8c45fSAndroid Build Coastguard Worker eglQuerySurface(mDisplay, surface, EGL_HEIGHT, &h);
149*38e8c45fSAndroid Build Coastguard Worker glViewport(0, 0, w, h);
150*38e8c45fSAndroid Build Coastguard Worker
151*38e8c45fSAndroid Build Coastguard Worker return true;
152*38e8c45fSAndroid Build Coastguard Worker }
153*38e8c45fSAndroid Build Coastguard Worker
createSurfaceTexture(uint32_t w,uint32_t h,sp<GLConsumer> * glConsumer,EGLSurface * surface,GLuint * name)154*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::createSurfaceTexture(uint32_t w, uint32_t h,
155*38e8c45fSAndroid Build Coastguard Worker sp<GLConsumer>* glConsumer, EGLSurface* surface,
156*38e8c45fSAndroid Build Coastguard Worker GLuint* name) {
157*38e8c45fSAndroid Build Coastguard Worker if (!makeCurrent(mDummySurface)) {
158*38e8c45fSAndroid Build Coastguard Worker return false;
159*38e8c45fSAndroid Build Coastguard Worker }
160*38e8c45fSAndroid Build Coastguard Worker
161*38e8c45fSAndroid Build Coastguard Worker *name = 0;
162*38e8c45fSAndroid Build Coastguard Worker glGenTextures(1, name);
163*38e8c45fSAndroid Build Coastguard Worker if (*name == 0) {
164*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "glGenTextures error: %#x\n", glGetError());
165*38e8c45fSAndroid Build Coastguard Worker return false;
166*38e8c45fSAndroid Build Coastguard Worker }
167*38e8c45fSAndroid Build Coastguard Worker
168*38e8c45fSAndroid Build Coastguard Worker return createNamedSurfaceTexture(*name, w, h, glConsumer, surface);
169*38e8c45fSAndroid Build Coastguard Worker }
170*38e8c45fSAndroid Build Coastguard Worker
destroySurface(EGLSurface * surface)171*38e8c45fSAndroid Build Coastguard Worker void GLHelper::destroySurface(EGLSurface* surface) {
172*38e8c45fSAndroid Build Coastguard Worker if (eglGetCurrentSurface(EGL_READ) == *surface ||
173*38e8c45fSAndroid Build Coastguard Worker eglGetCurrentSurface(EGL_DRAW) == *surface) {
174*38e8c45fSAndroid Build Coastguard Worker eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
175*38e8c45fSAndroid Build Coastguard Worker EGL_NO_CONTEXT);
176*38e8c45fSAndroid Build Coastguard Worker }
177*38e8c45fSAndroid Build Coastguard Worker eglDestroySurface(mDisplay, *surface);
178*38e8c45fSAndroid Build Coastguard Worker *surface = EGL_NO_SURFACE;
179*38e8c45fSAndroid Build Coastguard Worker }
180*38e8c45fSAndroid Build Coastguard Worker
swapBuffers(EGLSurface surface)181*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::swapBuffers(EGLSurface surface) {
182*38e8c45fSAndroid Build Coastguard Worker EGLint result;
183*38e8c45fSAndroid Build Coastguard Worker result = eglSwapBuffers(mDisplay, surface);
184*38e8c45fSAndroid Build Coastguard Worker if (result != EGL_TRUE) {
185*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "eglSwapBuffers error: %#x\n", eglGetError());
186*38e8c45fSAndroid Build Coastguard Worker return false;
187*38e8c45fSAndroid Build Coastguard Worker }
188*38e8c45fSAndroid Build Coastguard Worker return true;
189*38e8c45fSAndroid Build Coastguard Worker }
190*38e8c45fSAndroid Build Coastguard Worker
getShaderProgram(const char * name,GLuint * outPgm)191*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::getShaderProgram(const char* name, GLuint* outPgm) {
192*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < mNumShaders; i++) {
193*38e8c45fSAndroid Build Coastguard Worker if (strcmp(mShaderDescs[i].name, name) == 0) {
194*38e8c45fSAndroid Build Coastguard Worker *outPgm = mShaderPrograms[i];
195*38e8c45fSAndroid Build Coastguard Worker return true;
196*38e8c45fSAndroid Build Coastguard Worker }
197*38e8c45fSAndroid Build Coastguard Worker }
198*38e8c45fSAndroid Build Coastguard Worker
199*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "unknown shader name: \"%s\"\n", name);
200*38e8c45fSAndroid Build Coastguard Worker
201*38e8c45fSAndroid Build Coastguard Worker return false;
202*38e8c45fSAndroid Build Coastguard Worker }
203*38e8c45fSAndroid Build Coastguard Worker
createNamedSurfaceTexture(GLuint name,uint32_t w,uint32_t h,sp<GLConsumer> * glConsumer,EGLSurface * surface)204*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h,
205*38e8c45fSAndroid Build Coastguard Worker sp<GLConsumer>* glConsumer, EGLSurface* surface) {
206*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
207*38e8c45fSAndroid Build Coastguard Worker sp<GLConsumer> glc = new GLConsumer(name, GL_TEXTURE_EXTERNAL_OES, false, true);
208*38e8c45fSAndroid Build Coastguard Worker glc->setDefaultBufferSize(w, h);
209*38e8c45fSAndroid Build Coastguard Worker glc->getSurface()->setMaxDequeuedBufferCount(2);
210*38e8c45fSAndroid Build Coastguard Worker glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
211*38e8c45fSAndroid Build Coastguard Worker
212*38e8c45fSAndroid Build Coastguard Worker sp<ANativeWindow> anw = glc->getSurface();
213*38e8c45fSAndroid Build Coastguard Worker #else
214*38e8c45fSAndroid Build Coastguard Worker sp<IGraphicBufferProducer> producer;
215*38e8c45fSAndroid Build Coastguard Worker sp<IGraphicBufferConsumer> consumer;
216*38e8c45fSAndroid Build Coastguard Worker BufferQueue::createBufferQueue(&producer, &consumer);
217*38e8c45fSAndroid Build Coastguard Worker sp<GLConsumer> glc = new GLConsumer(consumer, name,
218*38e8c45fSAndroid Build Coastguard Worker GL_TEXTURE_EXTERNAL_OES, false, true);
219*38e8c45fSAndroid Build Coastguard Worker glc->setDefaultBufferSize(w, h);
220*38e8c45fSAndroid Build Coastguard Worker producer->setMaxDequeuedBufferCount(2);
221*38e8c45fSAndroid Build Coastguard Worker glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
222*38e8c45fSAndroid Build Coastguard Worker
223*38e8c45fSAndroid Build Coastguard Worker sp<ANativeWindow> anw = new Surface(producer);
224*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
225*38e8c45fSAndroid Build Coastguard Worker EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), nullptr);
226*38e8c45fSAndroid Build Coastguard Worker if (s == EGL_NO_SURFACE) {
227*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError());
228*38e8c45fSAndroid Build Coastguard Worker return false;
229*38e8c45fSAndroid Build Coastguard Worker }
230*38e8c45fSAndroid Build Coastguard Worker
231*38e8c45fSAndroid Build Coastguard Worker *glConsumer = glc;
232*38e8c45fSAndroid Build Coastguard Worker *surface = s;
233*38e8c45fSAndroid Build Coastguard Worker return true;
234*38e8c45fSAndroid Build Coastguard Worker }
235*38e8c45fSAndroid Build Coastguard Worker
computeWindowScale(uint32_t w,uint32_t h,float * scale)236*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::computeWindowScale(uint32_t w, uint32_t h, float* scale) {
237*38e8c45fSAndroid Build Coastguard Worker ui::DisplayMode mode;
238*38e8c45fSAndroid Build Coastguard Worker status_t err = mSurfaceComposerClient->getActiveDisplayMode(mDisplayToken, &mode);
239*38e8c45fSAndroid Build Coastguard Worker if (err != NO_ERROR) {
240*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "SurfaceComposer::getActiveDisplayMode failed: %#x\n", err);
241*38e8c45fSAndroid Build Coastguard Worker return false;
242*38e8c45fSAndroid Build Coastguard Worker }
243*38e8c45fSAndroid Build Coastguard Worker
244*38e8c45fSAndroid Build Coastguard Worker float scaleX = static_cast<float>(mode.resolution.getWidth()) / w;
245*38e8c45fSAndroid Build Coastguard Worker float scaleY = static_cast<float>(mode.resolution.getHeight()) / h;
246*38e8c45fSAndroid Build Coastguard Worker *scale = scaleX < scaleY ? scaleX : scaleY;
247*38e8c45fSAndroid Build Coastguard Worker
248*38e8c45fSAndroid Build Coastguard Worker return true;
249*38e8c45fSAndroid Build Coastguard Worker }
250*38e8c45fSAndroid Build Coastguard Worker
createWindowSurface(uint32_t w,uint32_t h,sp<SurfaceControl> * surfaceControl,EGLSurface * surface)251*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::createWindowSurface(uint32_t w, uint32_t h,
252*38e8c45fSAndroid Build Coastguard Worker sp<SurfaceControl>* surfaceControl, EGLSurface* surface) {
253*38e8c45fSAndroid Build Coastguard Worker bool result;
254*38e8c45fSAndroid Build Coastguard Worker status_t err;
255*38e8c45fSAndroid Build Coastguard Worker
256*38e8c45fSAndroid Build Coastguard Worker if (mSurfaceComposerClient == nullptr) {
257*38e8c45fSAndroid Build Coastguard Worker mSurfaceComposerClient = new SurfaceComposerClient;
258*38e8c45fSAndroid Build Coastguard Worker }
259*38e8c45fSAndroid Build Coastguard Worker err = mSurfaceComposerClient->initCheck();
260*38e8c45fSAndroid Build Coastguard Worker if (err != NO_ERROR) {
261*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "SurfaceComposerClient::initCheck error: %#x\n", err);
262*38e8c45fSAndroid Build Coastguard Worker return false;
263*38e8c45fSAndroid Build Coastguard Worker }
264*38e8c45fSAndroid Build Coastguard Worker
265*38e8c45fSAndroid Build Coastguard Worker sp<SurfaceControl> sc = mSurfaceComposerClient->createSurface(
266*38e8c45fSAndroid Build Coastguard Worker String8("Benchmark"), w, h, PIXEL_FORMAT_RGBA_8888, 0);
267*38e8c45fSAndroid Build Coastguard Worker if (sc == nullptr || !sc->isValid()) {
268*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "Failed to create SurfaceControl.\n");
269*38e8c45fSAndroid Build Coastguard Worker return false;
270*38e8c45fSAndroid Build Coastguard Worker }
271*38e8c45fSAndroid Build Coastguard Worker
272*38e8c45fSAndroid Build Coastguard Worker float scale;
273*38e8c45fSAndroid Build Coastguard Worker result = computeWindowScale(w, h, &scale);
274*38e8c45fSAndroid Build Coastguard Worker if (!result) {
275*38e8c45fSAndroid Build Coastguard Worker return false;
276*38e8c45fSAndroid Build Coastguard Worker }
277*38e8c45fSAndroid Build Coastguard Worker
278*38e8c45fSAndroid Build Coastguard Worker SurfaceComposerClient::Transaction{}.setLayer(sc, 0x7FFFFFFF)
279*38e8c45fSAndroid Build Coastguard Worker .setMatrix(sc, scale, 0.0f, 0.0f, scale)
280*38e8c45fSAndroid Build Coastguard Worker .show(sc)
281*38e8c45fSAndroid Build Coastguard Worker .apply();
282*38e8c45fSAndroid Build Coastguard Worker
283*38e8c45fSAndroid Build Coastguard Worker sp<ANativeWindow> anw = sc->getSurface();
284*38e8c45fSAndroid Build Coastguard Worker EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), nullptr);
285*38e8c45fSAndroid Build Coastguard Worker if (s == EGL_NO_SURFACE) {
286*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError());
287*38e8c45fSAndroid Build Coastguard Worker return false;
288*38e8c45fSAndroid Build Coastguard Worker }
289*38e8c45fSAndroid Build Coastguard Worker
290*38e8c45fSAndroid Build Coastguard Worker *surfaceControl = sc;
291*38e8c45fSAndroid Build Coastguard Worker *surface = s;
292*38e8c45fSAndroid Build Coastguard Worker return true;
293*38e8c45fSAndroid Build Coastguard Worker }
294*38e8c45fSAndroid Build Coastguard Worker
compileShader(GLenum shaderType,const char * src,GLuint * outShader)295*38e8c45fSAndroid Build Coastguard Worker static bool compileShader(GLenum shaderType, const char* src,
296*38e8c45fSAndroid Build Coastguard Worker GLuint* outShader) {
297*38e8c45fSAndroid Build Coastguard Worker GLuint shader = glCreateShader(shaderType);
298*38e8c45fSAndroid Build Coastguard Worker if (shader == 0) {
299*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "glCreateShader error: %#x\n", glGetError());
300*38e8c45fSAndroid Build Coastguard Worker return false;
301*38e8c45fSAndroid Build Coastguard Worker }
302*38e8c45fSAndroid Build Coastguard Worker
303*38e8c45fSAndroid Build Coastguard Worker glShaderSource(shader, 1, &src, nullptr);
304*38e8c45fSAndroid Build Coastguard Worker glCompileShader(shader);
305*38e8c45fSAndroid Build Coastguard Worker
306*38e8c45fSAndroid Build Coastguard Worker GLint compiled = 0;
307*38e8c45fSAndroid Build Coastguard Worker glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
308*38e8c45fSAndroid Build Coastguard Worker if (!compiled) {
309*38e8c45fSAndroid Build Coastguard Worker GLint infoLen = 0;
310*38e8c45fSAndroid Build Coastguard Worker glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
311*38e8c45fSAndroid Build Coastguard Worker if (infoLen) {
312*38e8c45fSAndroid Build Coastguard Worker char* buf = new char[infoLen];
313*38e8c45fSAndroid Build Coastguard Worker if (buf) {
314*38e8c45fSAndroid Build Coastguard Worker glGetShaderInfoLog(shader, infoLen, nullptr, buf);
315*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "Shader compile log:\n%s\n", buf);
316*38e8c45fSAndroid Build Coastguard Worker delete[] buf;
317*38e8c45fSAndroid Build Coastguard Worker }
318*38e8c45fSAndroid Build Coastguard Worker }
319*38e8c45fSAndroid Build Coastguard Worker glDeleteShader(shader);
320*38e8c45fSAndroid Build Coastguard Worker return false;
321*38e8c45fSAndroid Build Coastguard Worker }
322*38e8c45fSAndroid Build Coastguard Worker *outShader = shader;
323*38e8c45fSAndroid Build Coastguard Worker return true;
324*38e8c45fSAndroid Build Coastguard Worker }
325*38e8c45fSAndroid Build Coastguard Worker
printShaderSource(const char * const * src)326*38e8c45fSAndroid Build Coastguard Worker static void printShaderSource(const char* const* src) {
327*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
328*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "%3zu: %s\n", i+1, src[i]);
329*38e8c45fSAndroid Build Coastguard Worker }
330*38e8c45fSAndroid Build Coastguard Worker }
331*38e8c45fSAndroid Build Coastguard Worker
makeShaderString(const char * const * src)332*38e8c45fSAndroid Build Coastguard Worker static const char* makeShaderString(const char* const* src) {
333*38e8c45fSAndroid Build Coastguard Worker size_t len = 0;
334*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
335*38e8c45fSAndroid Build Coastguard Worker // The +1 is for the '\n' that will be added.
336*38e8c45fSAndroid Build Coastguard Worker len += strlen(src[i]) + 1;
337*38e8c45fSAndroid Build Coastguard Worker }
338*38e8c45fSAndroid Build Coastguard Worker
339*38e8c45fSAndroid Build Coastguard Worker char* result = new char[len+1];
340*38e8c45fSAndroid Build Coastguard Worker char* end = result;
341*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
342*38e8c45fSAndroid Build Coastguard Worker strcpy(end, src[i]);
343*38e8c45fSAndroid Build Coastguard Worker end += strlen(src[i]);
344*38e8c45fSAndroid Build Coastguard Worker *end = '\n';
345*38e8c45fSAndroid Build Coastguard Worker end++;
346*38e8c45fSAndroid Build Coastguard Worker }
347*38e8c45fSAndroid Build Coastguard Worker *end = '\0';
348*38e8c45fSAndroid Build Coastguard Worker
349*38e8c45fSAndroid Build Coastguard Worker return result;
350*38e8c45fSAndroid Build Coastguard Worker }
351*38e8c45fSAndroid Build Coastguard Worker
compileShaderLines(GLenum shaderType,const char * const * lines,GLuint * outShader)352*38e8c45fSAndroid Build Coastguard Worker static bool compileShaderLines(GLenum shaderType, const char* const* lines,
353*38e8c45fSAndroid Build Coastguard Worker GLuint* outShader) {
354*38e8c45fSAndroid Build Coastguard Worker const char* src = makeShaderString(lines);
355*38e8c45fSAndroid Build Coastguard Worker bool result = compileShader(shaderType, src, outShader);
356*38e8c45fSAndroid Build Coastguard Worker if (!result) {
357*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "Shader source:\n");
358*38e8c45fSAndroid Build Coastguard Worker printShaderSource(lines);
359*38e8c45fSAndroid Build Coastguard Worker delete[] src;
360*38e8c45fSAndroid Build Coastguard Worker return false;
361*38e8c45fSAndroid Build Coastguard Worker }
362*38e8c45fSAndroid Build Coastguard Worker delete[] src;
363*38e8c45fSAndroid Build Coastguard Worker
364*38e8c45fSAndroid Build Coastguard Worker return true;
365*38e8c45fSAndroid Build Coastguard Worker }
366*38e8c45fSAndroid Build Coastguard Worker
linkShaderProgram(GLuint vs,GLuint fs,GLuint * outPgm)367*38e8c45fSAndroid Build Coastguard Worker static bool linkShaderProgram(GLuint vs, GLuint fs, GLuint* outPgm) {
368*38e8c45fSAndroid Build Coastguard Worker GLuint program = glCreateProgram();
369*38e8c45fSAndroid Build Coastguard Worker if (program == 0) {
370*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "glCreateProgram error: %#x\n", glGetError());
371*38e8c45fSAndroid Build Coastguard Worker return false;
372*38e8c45fSAndroid Build Coastguard Worker }
373*38e8c45fSAndroid Build Coastguard Worker
374*38e8c45fSAndroid Build Coastguard Worker glAttachShader(program, vs);
375*38e8c45fSAndroid Build Coastguard Worker glAttachShader(program, fs);
376*38e8c45fSAndroid Build Coastguard Worker glLinkProgram(program);
377*38e8c45fSAndroid Build Coastguard Worker GLint linkStatus = GL_FALSE;
378*38e8c45fSAndroid Build Coastguard Worker glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
379*38e8c45fSAndroid Build Coastguard Worker if (linkStatus != GL_TRUE) {
380*38e8c45fSAndroid Build Coastguard Worker GLint bufLength = 0;
381*38e8c45fSAndroid Build Coastguard Worker glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
382*38e8c45fSAndroid Build Coastguard Worker if (bufLength) {
383*38e8c45fSAndroid Build Coastguard Worker char* buf = new char[bufLength];
384*38e8c45fSAndroid Build Coastguard Worker if (buf) {
385*38e8c45fSAndroid Build Coastguard Worker glGetProgramInfoLog(program, bufLength, nullptr, buf);
386*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "Program link log:\n%s\n", buf);
387*38e8c45fSAndroid Build Coastguard Worker delete[] buf;
388*38e8c45fSAndroid Build Coastguard Worker }
389*38e8c45fSAndroid Build Coastguard Worker }
390*38e8c45fSAndroid Build Coastguard Worker glDeleteProgram(program);
391*38e8c45fSAndroid Build Coastguard Worker program = 0;
392*38e8c45fSAndroid Build Coastguard Worker }
393*38e8c45fSAndroid Build Coastguard Worker
394*38e8c45fSAndroid Build Coastguard Worker *outPgm = program;
395*38e8c45fSAndroid Build Coastguard Worker return program != 0;
396*38e8c45fSAndroid Build Coastguard Worker }
397*38e8c45fSAndroid Build Coastguard Worker
setUpShaders(const ShaderDesc * shaderDescs,size_t numShaders)398*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::setUpShaders(const ShaderDesc* shaderDescs, size_t numShaders) {
399*38e8c45fSAndroid Build Coastguard Worker mShaderPrograms = new GLuint[numShaders];
400*38e8c45fSAndroid Build Coastguard Worker bool result = true;
401*38e8c45fSAndroid Build Coastguard Worker
402*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < numShaders && result; i++) {
403*38e8c45fSAndroid Build Coastguard Worker GLuint vs, fs;
404*38e8c45fSAndroid Build Coastguard Worker
405*38e8c45fSAndroid Build Coastguard Worker result = compileShaderLines(GL_VERTEX_SHADER,
406*38e8c45fSAndroid Build Coastguard Worker shaderDescs[i].vertexShader, &vs);
407*38e8c45fSAndroid Build Coastguard Worker if (!result) {
408*38e8c45fSAndroid Build Coastguard Worker return false;
409*38e8c45fSAndroid Build Coastguard Worker }
410*38e8c45fSAndroid Build Coastguard Worker
411*38e8c45fSAndroid Build Coastguard Worker result = compileShaderLines(GL_FRAGMENT_SHADER,
412*38e8c45fSAndroid Build Coastguard Worker shaderDescs[i].fragmentShader, &fs);
413*38e8c45fSAndroid Build Coastguard Worker if (!result) {
414*38e8c45fSAndroid Build Coastguard Worker glDeleteShader(vs);
415*38e8c45fSAndroid Build Coastguard Worker return false;
416*38e8c45fSAndroid Build Coastguard Worker }
417*38e8c45fSAndroid Build Coastguard Worker
418*38e8c45fSAndroid Build Coastguard Worker result = linkShaderProgram(vs, fs, &mShaderPrograms[i]);
419*38e8c45fSAndroid Build Coastguard Worker glDeleteShader(vs);
420*38e8c45fSAndroid Build Coastguard Worker glDeleteShader(fs);
421*38e8c45fSAndroid Build Coastguard Worker }
422*38e8c45fSAndroid Build Coastguard Worker
423*38e8c45fSAndroid Build Coastguard Worker mNumShaders = numShaders;
424*38e8c45fSAndroid Build Coastguard Worker mShaderDescs = shaderDescs;
425*38e8c45fSAndroid Build Coastguard Worker
426*38e8c45fSAndroid Build Coastguard Worker return result;
427*38e8c45fSAndroid Build Coastguard Worker }
428*38e8c45fSAndroid Build Coastguard Worker
getDitherTexture(GLuint * outTexName)429*38e8c45fSAndroid Build Coastguard Worker bool GLHelper::getDitherTexture(GLuint* outTexName) {
430*38e8c45fSAndroid Build Coastguard Worker if (mDitherTexture == 0) {
431*38e8c45fSAndroid Build Coastguard Worker const uint8_t pattern[] = {
432*38e8c45fSAndroid Build Coastguard Worker 0, 8, 2, 10,
433*38e8c45fSAndroid Build Coastguard Worker 12, 4, 14, 6,
434*38e8c45fSAndroid Build Coastguard Worker 3, 11, 1, 9,
435*38e8c45fSAndroid Build Coastguard Worker 15, 7, 13, 5
436*38e8c45fSAndroid Build Coastguard Worker };
437*38e8c45fSAndroid Build Coastguard Worker
438*38e8c45fSAndroid Build Coastguard Worker glGenTextures(1, &mDitherTexture);
439*38e8c45fSAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, mDitherTexture);
440*38e8c45fSAndroid Build Coastguard Worker
441*38e8c45fSAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
442*38e8c45fSAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
443*38e8c45fSAndroid Build Coastguard Worker
444*38e8c45fSAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
445*38e8c45fSAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
446*38e8c45fSAndroid Build Coastguard Worker
447*38e8c45fSAndroid Build Coastguard Worker glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE,
448*38e8c45fSAndroid Build Coastguard Worker DITHER_KERNEL_SIZE, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &pattern);
449*38e8c45fSAndroid Build Coastguard Worker }
450*38e8c45fSAndroid Build Coastguard Worker
451*38e8c45fSAndroid Build Coastguard Worker *outTexName = mDitherTexture;
452*38e8c45fSAndroid Build Coastguard Worker
453*38e8c45fSAndroid Build Coastguard Worker return true;
454*38e8c45fSAndroid Build Coastguard Worker }
455*38e8c45fSAndroid Build Coastguard Worker
456*38e8c45fSAndroid Build Coastguard Worker }
457