SurfaceTexture_test.cpp revision 1876d13e45ae044d4c1f6f2ee176f52f22d8a26c
1d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis/*
2d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * Copyright (C) 2011 The Android Open Source Project
3d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis *
4d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
5d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * you may not use this file except in compliance with the License.
6d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * You may obtain a copy of the License at
7d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis *
8d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
9d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis *
10d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * Unless required by applicable law or agreed to in writing, software
11d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
12d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * See the License for the specific language governing permissions and
14d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis * limitations under the License.
15d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis */
16d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis//#define LOG_NDEBUG 0
185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
19d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <gtest/gtest.h>
20d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <gui/SurfaceTexture.h>
21d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <gui/SurfaceTextureClient.h>
22d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <ui/GraphicBuffer.h>
23d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <utils/String8.h>
245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis#include <utils/threads.h>
25d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
26d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <surfaceflinger/ISurfaceComposer.h>
27d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <surfaceflinger/Surface.h>
28d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <surfaceflinger/SurfaceComposerClient.h>
29d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
30d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <EGL/egl.h>
31d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <EGL/eglext.h>
32d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <GLES2/gl2.h>
33d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <GLES2/gl2ext.h>
34d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
35d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <ui/FramebufferNativeWindow.h>
36d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
37d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisnamespace android {
38d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
39d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisclass GLTest : public ::testing::Test {
40d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisprotected:
41d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
42d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    GLTest():
43d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglDisplay(EGL_NO_DISPLAY),
44d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglSurface(EGL_NO_SURFACE),
45d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglContext(EGL_NO_CONTEXT) {
46d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
47d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
48d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void SetUp() {
49d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
50d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
51d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
52d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
53d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint majorVersion;
54d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint minorVersion;
55d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
56d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
57d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglVersionMajor", majorVersion);
58d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglVersionMajor", minorVersion);
59d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
60d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint numConfigs = 0;
611876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
62d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                1, &numConfigs));
63d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
64d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
65d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
66d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (displaySecsEnv != NULL) {
67d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mDisplaySecs = atoi(displaySecsEnv);
68d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (mDisplaySecs < 0) {
69d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                mDisplaySecs = 0;
70d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
71d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
72d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mDisplaySecs = 0;
73d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
74d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
75d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mDisplaySecs > 0) {
76d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mComposerClient = new SurfaceComposerClient;
77d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
78d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
79fc850124b35abd00a31e9bcf57e14e0fa74f4cd7Jamie Gennis            mSurfaceControl = mComposerClient->createSurface(
80d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    String8("Test Surface"), 0,
81d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    getSurfaceWidth(), getSurfaceHeight(),
82d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    PIXEL_FORMAT_RGB_888, 0);
83d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
84d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_TRUE(mSurfaceControl != NULL);
85d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_TRUE(mSurfaceControl->isValid());
86d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
87d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction());
88d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
89d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
90d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction());
91d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
92d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            sp<ANativeWindow> window = mSurfaceControl->getSurface();
931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
94d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    window.get(), NULL);
95d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
96d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGLint pbufferAttribs[] = {
97d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_WIDTH, getSurfaceWidth(),
98d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_HEIGHT, getSurfaceHeight(),
99d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_NONE };
100d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
1011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
102d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    pbufferAttribs);
103d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
104d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
105d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
106d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
1071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
108d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                getContextAttribs());
109d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
110d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
111d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
112d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
113d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                mEglContext));
114d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
115d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
116d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint w, h;
117d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
118d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
119d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
120d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
121d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglSurfaceWidth", w);
122d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglSurfaceHeight", h);
123d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
124d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glViewport(0, 0, w, h);
125d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
126d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
127d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
128d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void TearDown() {
129d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        // Display the result
130d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
131d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglSwapBuffers(mEglDisplay, mEglSurface);
132d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            sleep(mDisplaySecs);
133d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
134d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
135d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mComposerClient != NULL) {
136d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mComposerClient->dispose();
137d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
138d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglContext != EGL_NO_CONTEXT) {
139d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglDestroyContext(mEglDisplay, mEglContext);
140d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
141d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglSurface != EGL_NO_SURFACE) {
142d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglDestroySurface(mEglDisplay, mEglSurface);
143d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
144d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglDisplay != EGL_NO_DISPLAY) {
145d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
146d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    EGL_NO_CONTEXT);
147d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglTerminate(mEglDisplay);
148d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
149d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
150d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
151d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
152d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint const* getConfigAttribs() {
153d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        static EGLint sDefaultConfigAttribs[] = {
154d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
155d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
156d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_RED_SIZE, 8,
157d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_GREEN_SIZE, 8,
158d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_BLUE_SIZE, 8,
159d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_ALPHA_SIZE, 8,
160d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_DEPTH_SIZE, 16,
161d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_STENCIL_SIZE, 8,
162d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_NONE };
163d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
164d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        return sDefaultConfigAttribs;
165d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
166d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
167d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint const* getContextAttribs() {
168d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        static EGLint sDefaultContextAttribs[] = {
169d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_CONTEXT_CLIENT_VERSION, 2,
170d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_NONE };
171d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
172d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        return sDefaultContextAttribs;
173d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
174d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
175d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint getSurfaceWidth() {
176d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        return 64;
177d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
178d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
179d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint getSurfaceHeight() {
180d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        return 64;
181d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
182d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
183d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) {
184d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLuint shader = glCreateShader(shaderType);
185d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
186d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (shader) {
187d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            glShaderSource(shader, 1, &pSource, NULL);
188d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
189d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            glCompileShader(shader);
190d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
191d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GLint compiled = 0;
192d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
193d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
194d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!compiled) {
195d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                GLint infoLen = 0;
196d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
197d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
198d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                if (infoLen) {
199d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    char* buf = (char*) malloc(infoLen);
200d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    if (buf) {
201d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        glGetShaderInfoLog(shader, infoLen, NULL, buf);
202d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        printf("Shader compile log:\n%s\n", buf);
203d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        free(buf);
204d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        FAIL();
205d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    }
206d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                } else {
207d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    char* buf = (char*) malloc(0x1000);
208d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    if (buf) {
209d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        glGetShaderInfoLog(shader, 0x1000, NULL, buf);
210d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        printf("Shader compile log:\n%s\n", buf);
211d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        free(buf);
212d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        FAIL();
213d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    }
214d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                }
215d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                glDeleteShader(shader);
216d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                shader = 0;
217d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
218d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
219d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_TRUE(shader != 0);
220d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        *outShader = shader;
221d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
222d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
223d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    void createProgram(const char* pVertexSource, const char* pFragmentSource,
224d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GLuint* outPgm) {
225d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLuint vertexShader, fragmentShader;
226d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {
227d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            SCOPED_TRACE("compiling vertex shader");
228d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
229d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (HasFatalFailure()) {
230d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                return;
231d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
232d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
233d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {
234d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            SCOPED_TRACE("compiling fragment shader");
235d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
236d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (HasFatalFailure()) {
237d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                return;
238d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
239d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
240d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
241d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLuint program = glCreateProgram();
242d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
243d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (program) {
244d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            glAttachShader(program, vertexShader);
245d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
246d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            glAttachShader(program, fragmentShader);
247d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
248d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            glLinkProgram(program);
249d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GLint linkStatus = GL_FALSE;
250d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
251d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (linkStatus != GL_TRUE) {
252d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                GLint bufLength = 0;
253d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
254d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                if (bufLength) {
255d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    char* buf = (char*) malloc(bufLength);
256d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    if (buf) {
257d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        glGetProgramInfoLog(program, bufLength, NULL, buf);
258d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        printf("Program link log:\n%s\n", buf);
259d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        free(buf);
260d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        FAIL();
261d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    }
262d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                }
263d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                glDeleteProgram(program);
264d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                program = 0;
265d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
266d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
267d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glDeleteShader(vertexShader);
268d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glDeleteShader(fragmentShader);
269d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_TRUE(program != 0);
270d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        *outPgm = program;
271d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
272d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
273824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis    static int abs(int value) {
274824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        return value > 0 ? value : -value;
275824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis    }
276824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis
277d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ::testing::AssertionResult checkPixel(int x, int y, int r,
278824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis            int g, int b, int a, int tolerance=2) {
279d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLubyte pixel[4];
280d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        String8 msg;
281d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
282d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLenum err = glGetError();
283d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (err != GL_NO_ERROR) {
284d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("error reading pixel: %#x", err);
285d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            while ((err = glGetError()) != GL_NO_ERROR) {
286d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += String8::format(", %#x", err);
287d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
288d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            fprintf(stderr, "pixel check failure: %s\n", msg.string());
289d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionFailure(
290d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    ::testing::Message(msg.string()));
291d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
292824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
293d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("r(%d isn't %d)", pixel[0], r);
294d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
295824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
296d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
297d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
298d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
299d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("g(%d isn't %d)", pixel[1], g);
300d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
301824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
302d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
303d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
304d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
305d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("b(%d isn't %d)", pixel[2], b);
306d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
307824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
308d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
309d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
310d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
311d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("a(%d isn't %d)", pixel[3], a);
312d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
313d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (!msg.isEmpty()) {
314d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            fprintf(stderr, "pixel check failure: %s\n", msg.string());
315d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionFailure(
316d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    ::testing::Message(msg.string()));
317d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
318d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionSuccess();
319d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
320d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
321d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
322d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int mDisplaySecs;
323d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceComposerClient> mComposerClient;
324d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceControl> mSurfaceControl;
325d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
326d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLDisplay mEglDisplay;
327d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLSurface mEglSurface;
328d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLContext mEglContext;
3291876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EGLConfig  mGlConfig;
330d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis};
331d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
332d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// XXX: Code above this point should live elsewhere
333d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
334d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisclass SurfaceTextureGLTest : public GLTest {
335d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisprotected:
336d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    static const GLint TEX_ID = 123;
337d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
338d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void SetUp() {
339d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLTest::SetUp();
340d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mST = new SurfaceTexture(TEX_ID);
341d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mSTC = new SurfaceTextureClient(mST);
342d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mANW = mSTC;
343d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
344d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const char vsrc[] =
345d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "attribute vec4 vPosition;\n"
346d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "varying vec2 texCoords;\n"
347d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "uniform mat4 texMatrix;\n"
348d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "void main() {\n"
349d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
350d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
351d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "  gl_Position = vPosition;\n"
352d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "}\n";
353d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
354d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const char fsrc[] =
355d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "#extension GL_OES_EGL_image_external : require\n"
356d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "precision mediump float;\n"
357d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "uniform samplerExternalOES texSampler;\n"
358d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "varying vec2 texCoords;\n"
359d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "void main() {\n"
360d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "  gl_FragColor = texture2D(texSampler, texCoords);\n"
361d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            "}\n";
362d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
363d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {
364d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            SCOPED_TRACE("creating shader program");
365d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            createProgram(vsrc, fsrc, &mPgm);
366d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (HasFatalFailure()) {
367d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                return;
368d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
369d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
370d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
371d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
372d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
373d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(-1, mPositionHandle);
374d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
375d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
376d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(-1, mTexSamplerHandle);
377d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
378d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
379d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(-1, mTexMatrixHandle);
380d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
381d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
382d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    // drawTexture draws the SurfaceTexture over the entire GL viewport.
383d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    void drawTexture() {
384d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const GLfloat triangleVertices[] = {
385d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            -1.0f, 1.0f,
386d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            -1.0f, -1.0f,
387d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            1.0f, -1.0f,
388d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            1.0f, 1.0f,
389d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        };
390d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
391d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices);
392d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
393d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glEnableVertexAttribArray(mPositionHandle);
394d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
395d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
396d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glUseProgram(mPgm);
397d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glUniform1i(mTexSamplerHandle, 0);
398d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
399d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
400d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
401d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
4021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
4031876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        // they're setting the defautls for that target, but when hacking things
4041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        // to use GL_TEXTURE_2D they are needed to achieve the same behavior.
4051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
4071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
4091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4101876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
4111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
4131876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
414d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLfloat texMatrix[16];
415d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mST->getTransformMatrix(texMatrix);
416d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
417d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
418d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
419d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
420d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
421d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
422d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceTexture> mST;
423d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceTextureClient> mSTC;
424d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<ANativeWindow> mANW;
425d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
426d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    GLuint mPgm;
427d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    GLint mPositionHandle;
428d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    GLint mTexSamplerHandle;
429d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    GLint mTexMatrixHandle;
430d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis};
431d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
432d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// Fill a YV12 buffer with a multi-colored checkerboard pattern
433d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisvoid fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
434d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int blockWidth = w > 16 ? w / 16 : 1;
435d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int blockHeight = h > 16 ? h / 16 : 1;
436d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int yuvTexOffsetY = 0;
437d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideY = stride;
438d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetV = yuvTexStrideY * h;
439d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
440d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
441d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideU = yuvTexStrideV;
442d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int x = 0; x < w; x++) {
443d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        for (int y = 0; y < h; y++) {
444d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            int parityX = (x / blockWidth) & 1;
445d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            int parityY = (y / blockHeight) & 1;
446d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
447d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
448d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (x < w / 2 && y < h / 2) {
449d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
450d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                if (x * 2 < w / 2 && y * 2 < h / 2) {
451d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
452d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
453d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
454d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
455d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        intensity;
456d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                }
457d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
458d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
459d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
460d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
461d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
462d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// Fill a YV12 buffer with red outside a given rectangle and green inside it.
463d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisvoid fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
464d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const android_native_rect_t& rect) {
465d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int yuvTexOffsetY = 0;
466d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideY = stride;
467d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetV = yuvTexStrideY * h;
468d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
469d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
470d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideU = yuvTexStrideV;
471d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int x = 0; x < w; x++) {
472d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        for (int y = 0; y < h; y++) {
473d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            bool inside = rect.left <= x && x < rect.right &&
474d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    rect.top <= y && y < rect.bottom;
475d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
476d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (x < w / 2 && y < h / 2) {
477d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                bool inside = rect.left <= 2*x && 2*x < rect.right &&
478d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        rect.top <= 2*y && 2*y < rect.bottom;
479d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
480d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
481d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        inside ? 16 : 255;
482d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
483d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
484d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
485d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
486d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
4871876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennisvoid fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
4881876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const size_t PIXEL_SIZE = 4;
4891876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    for (int x = 0; x < w; x++) {
4901876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        for (int y = 0; y < h; y++) {
4911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            off_t offset = (y * stride + x) * PIXEL_SIZE;
4921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            for (int c = 0; c < 4; c++) {
4931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                int parityX = (x / (1 << (c+2))) & 1;
4941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                int parityY = (y / (1 << (c+2))) & 1;
4951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
4961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            }
4971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        }
4981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    }
4991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
5001876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
501d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
5021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
5031876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
504d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
505d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
5061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
507d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
508d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
509d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
510697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    ANativeWindowBuffer* anb;
511d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
512d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_TRUE(anb != NULL);
513d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
514d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
515d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
516d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
517d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    // Fill the buffer with the a checkerboard pattern
518d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    uint8_t* img = NULL;
519d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
5201876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
521d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->unlock();
522d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
523d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
524d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    mST->updateTexImage();
525d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
526d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
527d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
528d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
529d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    drawTexture();
530d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
531d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
532d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
533d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
534d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
535d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
536d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(22, 44, 247,  70, 255, 255));
537d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(45, 52, 209,  32, 235, 255));
538d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(52, 51, 100, 255,  73, 255));
539d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255));
540d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(31,  9, 148,  71, 110, 255));
541d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255));
542d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255));
543d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
544d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
545d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// XXX: This test is disabled because it it currently broken on all devices to
546d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// which I have access.  Some of the checkPixel calls are not correct because
547d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// I just copied them from the npot test above and haven't bothered to figure
548d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// out the correct values.
549d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) {
5501876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
5511876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
552d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
553d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
5541876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
555d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
556d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
557d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
558697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    ANativeWindowBuffer* anb;
559d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
560d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_TRUE(anb != NULL);
561d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
562d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
563d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
564d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
565d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    // Fill the buffer with the a checkerboard pattern
566d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    uint8_t* img = NULL;
567d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
5681876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
569d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->unlock();
570d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
571d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
572d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    mST->updateTexImage();
573d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
574d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
575d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
576d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
577d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    drawTexture();
578d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
579d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
580d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
581d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
582d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
583d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
584d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(22, 19, 247,  70, 255, 255));
585d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(45, 11, 209,  32, 235, 255));
586d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(52, 12, 100, 255,  73, 255));
587d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 7, 32, 155,   0, 118, 255));
588d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(31, 54, 148,  71, 110, 255));
589d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(29, 28, 255, 127, 255, 255));
590d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(36, 41, 155,  29,   0, 255));
591d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
592d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
593d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
5941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
5951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
596d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
597d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
5981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
599d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
600d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
601d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
602d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    android_native_rect_t crops[] = {
603d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {4, 6, 22, 36},
604d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {0, 6, 22, 36},
605d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {4, 0, 22, 36},
6061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        {4, 6, texWidth, 36},
6071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        {4, 6, 22, texHeight},
608d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    };
609d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
610d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int i = 0; i < 5; i++) {
611d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const android_native_rect_t& crop(crops[i]);
612d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", crop.left,
613d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                crop.top, crop.right, crop.bottom).string());
614d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
615d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
616d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
617697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer* anb;
618d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
619d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_TRUE(anb != NULL);
620d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
621d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
622d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
623d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
624d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        uint8_t* img = NULL;
625d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
6261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
627d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        buf->unlock();
628d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
629d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
630d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mST->updateTexImage();
631d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
632d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glClearColor(0.2, 0.2, 0.2, 0.2);
633d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
634d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
635d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        drawTexture();
636d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
637d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
638d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
639d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
640d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
641d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
642d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
643d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
644d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
645d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
646d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
647d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
648d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
649d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
650d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
651d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
6521876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis// XXX: This test is disabled because there are currently no drivers that can
6531876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target.
6541876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie GennisTEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledRGBABufferNpot) {
6551876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
6561876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
6571876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6581876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
6591876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
6601876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
6611876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
6621876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6631876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    android_native_buffer_t* anb;
6641876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
6651876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_TRUE(anb != NULL);
6661876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6671876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
6681876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
6691876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6701876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    // Fill the buffer with the a checkerboard pattern
6711876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    uint8_t* img = NULL;
6721876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
6731876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride());
6741876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    buf->unlock();
6751876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
6761876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6771876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->updateTexImage();
6781876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6791876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
6801876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
6811876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6821876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
6831876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6841876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
6851876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
6861876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
6871876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
6881876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
6891876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
6901876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(24, 63,  35, 231, 231,  35));
6911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(19, 40,  87, 179,  35,  35));
6921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
6931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
6941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(37, 33,  35, 231, 231, 231));
6951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
6961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(36, 47, 231,  35, 231, 231));
6971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(24, 63,  35, 231, 231,  35));
6981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(48,  3, 231, 231,  35,  35));
6991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
7001876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(24, 25, 191, 191, 231, 231));
7011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(10,  9,  93,  93, 231, 231));
7021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
7031876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(56, 31,  35, 231, 231,  35));
7041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
7051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
7061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis// XXX: This test is disabled because there are currently no drivers that can
7081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target.
7091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie GennisTEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledRGBABufferPow2) {
7101876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
7111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
7121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7131876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
7141876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
7151876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
7161876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
7171876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7181876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    android_native_buffer_t* anb;
7191876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
7201876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_TRUE(anb != NULL);
7211876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7221876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
7231876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
7241876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7251876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    // Fill the buffer with the a checkerboard pattern
7261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    uint8_t* img = NULL;
7271876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
7281876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride());
7291876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    buf->unlock();
7301876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
7311876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7321876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->updateTexImage();
7331876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7341876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
7351876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
7361876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7371876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
7381876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7391876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
7401876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
7411876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
7421876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
7431876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7441876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
7451876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
7461876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
7471876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
7481876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
7491876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
7501876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
7511876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
7521876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
7531876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
7541876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
7551876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
7561876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
7571876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
7581876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
7591876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
7601876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
7611876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7621876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis// XXX: This test is disabled because there are currently no drivers that can
7631876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target.
7641876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie GennisTEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromGLFilledRGBABufferPow2) {
7651876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
7661876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
7671876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7681876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->setDefaultBufferSize(texWidth, texHeight);
7691876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7701876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    // Do the producer side of things
7711876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
7721876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mANW.get(), NULL);
7731876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
7741876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
7751876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7761876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
7771876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglContext));
7781876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
7791876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7801876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
7811876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
7821876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7831876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glEnable(GL_SCISSOR_TEST);
7841876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(4, 4, 4, 4);
7851876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
7861876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
7871876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7881876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(24, 48, 4, 4);
7891876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.0, 1.0, 0.0, 1.0);
7901876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
7911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(37, 17, 4, 4);
7931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.0, 0.0, 1.0, 1.0);
7941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
7951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    eglSwapBuffers(mEglDisplay, stcEglSurface);
7971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
7981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    // Do the consumer side of things
7991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
8001876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglContext));
8011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
8021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
8031876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glDisable(GL_SCISSOR_TEST);
8041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
8051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->updateTexImage();
8061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
8071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
8081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
8091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
8101876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
8111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
8121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
8131876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
8141876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
8151876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
8161876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
8171876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
8181876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
8191876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
8201876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
8211876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
8221876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
8231876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
8241876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
8251876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
8261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
8271876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
8281876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
8291876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
8301876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
8311876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
8321876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
8331876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
8341876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
8355451d15ee209f29d64beea87583f7058dee69911Jamie Gennis/*
8365451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * This test is for testing GL -> GL texture streaming via SurfaceTexture.  It
8375451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * contains functionality to create a producer thread that will perform GL
8385451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * rendering to an ANativeWindow that feeds frames to a SurfaceTexture.
8395451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * Additionally it supports interlocking the producer and consumer threads so
8405451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * that a specific sequence of calls can be deterministically created by the
8415451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * test.
8425451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
8435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * The intended usage is as follows:
8445451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
8455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * TEST_F(...) {
8465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     class PT : public ProducerThread {
8475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *         virtual void render() {
8485451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *             ...
8495451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *             swapBuffers();
8505451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *         }
8515451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     };
8525451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
8535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     runProducerThread(new PT());
8545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
8555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // The order of these calls will vary from test to test and may include
8565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // multiple frames and additional operations (e.g. GL rendering from the
8575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // texture).
8585451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     fc->waitForFrame();
8595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     mST->updateTexImage();
8605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     fc->finishFrame();
8615451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * }
8625451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
8635451d15ee209f29d64beea87583f7058dee69911Jamie Gennis */
8645451d15ee209f29d64beea87583f7058dee69911Jamie Gennisclass SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
8655451d15ee209f29d64beea87583f7058dee69911Jamie Gennisprotected:
8665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
8675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // ProducerThread is an abstract base class to simplify the creation of
8685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // OpenGL ES frame producer threads.
8695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class ProducerThread : public Thread {
8705451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    public:
8715451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual ~ProducerThread() {
8725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
8735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
8745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void setEglObjects(EGLDisplay producerEglDisplay,
8755451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                EGLSurface producerEglSurface,
8765451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                EGLContext producerEglContext) {
8775451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglDisplay = producerEglDisplay;
8785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglSurface = producerEglSurface;
8795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglContext = producerEglContext;
8805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
8815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
8825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual bool threadLoop() {
8835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface,
8845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                    mProducerEglSurface, mProducerEglContext);
8855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            render();
8865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
8875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                    EGL_NO_CONTEXT);
8885451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            return false;
8895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
8905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
8915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    protected:
8925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() = 0;
8935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
8945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void swapBuffers() {
8955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface);
8965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
8975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
8985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLDisplay mProducerEglDisplay;
8995451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLSurface mProducerEglSurface;
9005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLContext mProducerEglContext;
9015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
9025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9035451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // FrameCondition is a utility class for interlocking between the producer
9045451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // and consumer threads.  The FrameCondition object should be created and
9055451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // destroyed in the consumer thread only.  The consumer thread should set
9065451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // the FrameCondition as the FrameAvailableListener of the SurfaceTexture,
9075451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // and should call both waitForFrame and finishFrame once for each expected
9085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // frame.
9095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    //
9105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // This interlocking relies on the fact that onFrameAvailable gets called
9115451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // synchronously from SurfaceTexture::queueBuffer.
9125451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class FrameCondition : public SurfaceTexture::FrameAvailableListener {
9135451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    public:
9145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // waitForFrame waits for the next frame to arrive.  This should be
9155451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // called from the consumer thread once for every frame expected by the
9165451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // test.
9175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void waitForFrame() {
9185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            LOGV("+waitForFrame");
9195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
9205451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            status_t result = mFrameAvailableCondition.wait(mMutex);
9215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            LOGV("-waitForFrame");
9225451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
9235451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // Allow the producer to return from its swapBuffers call and continue
9255451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // on to produce the next frame.  This should be called by the consumer
9265451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // thread once for every frame expected by the test.
9275451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void finishFrame() {
9285451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            LOGV("+finishFrame");
9295451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
9305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mFrameFinishCondition.signal();
9315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            LOGV("-finishFrame");
9325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
9335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // This should be called by SurfaceTexture on the producer thread.
9355451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void onFrameAvailable() {
9365451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            LOGV("+onFrameAvailable");
9375451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
9385451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mFrameAvailableCondition.signal();
9395451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mFrameFinishCondition.wait(mMutex);
9405451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            LOGV("-onFrameAvailable");
9415451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
9425451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    protected:
9445451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Mutex mMutex;
9455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Condition mFrameAvailableCondition;
9465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Condition mFrameFinishCondition;
9475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
9485451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9495451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    SurfaceTextureGLToGLTest():
9505451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglSurface(EGL_NO_SURFACE),
9515451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglContext(EGL_NO_CONTEXT) {
9525451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
9535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    virtual void SetUp() {
9555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        SurfaceTextureGLTest::SetUp();
9565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLConfig myConfig = {0};
9585451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLint numConfigs = 0;
9595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
9605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                1, &numConfigs));
9615451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
9625451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9635451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
9645451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                mANW.get(), NULL);
9655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
9665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
9675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mProducerEglContext = eglCreateContext(mEglDisplay, myConfig,
9695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                EGL_NO_CONTEXT, getContextAttribs());
9705451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
9715451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
9725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC = new FrameCondition();
9745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mST->setFrameAvailableListener(mFC);
9755451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
9765451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9775451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    virtual void TearDown() {
9785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        if (mProducerThread != NULL) {
9795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerThread->requestExitAndWait();
9805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
9815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        if (mProducerEglContext != EGL_NO_CONTEXT) {
9825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglDestroyContext(mEglDisplay, mProducerEglContext);
9835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
9845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        if (mProducerEglSurface != EGL_NO_SURFACE) {
9855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglDestroySurface(mEglDisplay, mProducerEglSurface);
9865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
9875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mProducerThread.clear();
9885451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC.clear();
9895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
9905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    void runProducerThread(const sp<ProducerThread> producerThread) {
9925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        ASSERT_TRUE(mProducerThread == NULL);
9935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mProducerThread = producerThread;
9945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        producerThread->setEglObjects(mEglDisplay, mProducerEglSurface,
9955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                mProducerEglContext);
9965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        producerThread->run();
9975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
9985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
9995451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    EGLSurface mProducerEglSurface;
10005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    EGLContext mProducerEglContext;
10015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    sp<ProducerThread> mProducerThread;
10025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    sp<FrameCondition> mFC;
10035451d15ee209f29d64beea87583f7058dee69911Jamie Gennis};
10045451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10055451d15ee209f29d64beea87583f7058dee69911Jamie Gennis// XXX: This test is disabled because it causes hangs on some devices.
10065451d15ee209f29d64beea87583f7058dee69911Jamie GennisTEST_F(SurfaceTextureGLToGLTest, DISABLED_UpdateTexImageBeforeFrameFinishedWorks) {
10075451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
10085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
10095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
10105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClear(GL_COLOR_BUFFER_BIT);
10115451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            swapBuffers();
10125451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
10135451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
10145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10155451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
10165451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->waitForFrame();
10185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mST->updateTexImage();
10195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->finishFrame();
10205451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
1022d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
10235451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10242510d9576ff2c529d584082aa1098480a73079e4Jamie Gennis// XXX: This test is disabled because it causes hangs on some devices.
10252510d9576ff2c529d584082aa1098480a73079e4Jamie GennisTEST_F(SurfaceTextureGLToGLTest, DISABLED_UpdateTexImageAfterFrameFinishedWorks) {
10265451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
10275451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
10285451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
10295451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClear(GL_COLOR_BUFFER_BIT);
10305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            swapBuffers();
10315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
10325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
10335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
10355451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10365451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->waitForFrame();
10375451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->finishFrame();
10385451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mST->updateTexImage();
10395451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10405451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
10415451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
10425451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis// XXX: This test is disabled because it causes hangs on some devices.
10445451d15ee209f29d64beea87583f7058dee69911Jamie GennisTEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedUpdateTexImageBeforeFrameFinishedWorks) {
10455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    enum { NUM_ITERATIONS = 1024 };
10465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
10485451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
10495451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            for (int i = 0; i < NUM_ITERATIONS; i++) {
10505451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
10515451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClear(GL_COLOR_BUFFER_BIT);
10525451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                LOGV("+swapBuffers");
10535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                swapBuffers();
10545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                LOGV("-swapBuffers");
10555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            }
10565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
10575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
10585451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
10605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10615451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS; i++) {
10625451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->waitForFrame();
10635451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        LOGV("+updateTexImage");
10645451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mST->updateTexImage();
10655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        LOGV("-updateTexImage");
10665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->finishFrame();
10675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
10695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
10705451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
10715451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis// XXX: This test is disabled because it causes hangs on some devices.
10735451d15ee209f29d64beea87583f7058dee69911Jamie GennisTEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedUpdateTexImageAfterFrameFinishedWorks) {
10745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    enum { NUM_ITERATIONS = 1024 };
10755451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10765451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
10775451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
10785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            for (int i = 0; i < NUM_ITERATIONS; i++) {
10795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
10805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClear(GL_COLOR_BUFFER_BIT);
10815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                LOGV("+swapBuffers");
10825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                swapBuffers();
10835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                LOGV("-swapBuffers");
10845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            }
10855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
10865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
10875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10885451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
10895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS; i++) {
10915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->waitForFrame();
10925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->finishFrame();
10935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        LOGV("+updateTexImage");
10945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mST->updateTexImage();
10955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        LOGV("-updateTexImage");
10965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
10975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
10985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
10995451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
11005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
11015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis} // namespace android
1102