SurfaceTexture_test.cpp revision c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5da
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
172640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis#define LOG_TAG "SurfaceTexture_test"
185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis//#define LOG_NDEBUG 0
195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <gtest/gtest.h>
21d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <gui/SurfaceTexture.h>
22d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <gui/SurfaceTextureClient.h>
23d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <ui/GraphicBuffer.h>
24d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <utils/String8.h>
255451d15ee209f29d64beea87583f7058dee69911Jamie Gennis#include <utils/threads.h>
26d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
2790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h>
2890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
2990ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/SurfaceComposerClient.h>
30d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
31d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <EGL/egl.h>
32d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <EGL/eglext.h>
33d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <GLES2/gl2.h>
34d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <GLES2/gl2ext.h>
35d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
36d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <ui/FramebufferNativeWindow.h>
37d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
38d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisnamespace android {
39d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
40d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisclass GLTest : public ::testing::Test {
41d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisprotected:
42d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
43d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    GLTest():
44d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglDisplay(EGL_NO_DISPLAY),
45d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglSurface(EGL_NO_SURFACE),
46d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglContext(EGL_NO_CONTEXT) {
47d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
48d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
49d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void SetUp() {
50fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        const ::testing::TestInfo* const testInfo =
51fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            ::testing::UnitTest::GetInstance()->current_test_info();
52fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
53fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                testInfo->name());
54fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
55d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
56d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
57d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
58d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
59d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint majorVersion;
60d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint minorVersion;
61d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
62d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
63d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglVersionMajor", majorVersion);
64d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglVersionMajor", minorVersion);
65d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
66d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint numConfigs = 0;
671876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
68d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                1, &numConfigs));
69d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
70d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
71d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
72d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (displaySecsEnv != NULL) {
73d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mDisplaySecs = atoi(displaySecsEnv);
74d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (mDisplaySecs < 0) {
75d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                mDisplaySecs = 0;
76d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
77d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
78d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mDisplaySecs = 0;
79d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
80d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
81d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mDisplaySecs > 0) {
82d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mComposerClient = new SurfaceComposerClient;
83d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
84d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
85fc850124b35abd00a31e9bcf57e14e0fa74f4cd7Jamie Gennis            mSurfaceControl = mComposerClient->createSurface(
86d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    String8("Test Surface"), 0,
87d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    getSurfaceWidth(), getSurfaceHeight(),
88d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    PIXEL_FORMAT_RGB_888, 0);
89d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
90d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_TRUE(mSurfaceControl != NULL);
91d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_TRUE(mSurfaceControl->isValid());
92d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
93698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            SurfaceComposerClient::openGlobalTransaction();
945dd0c4fd7efcb99bdd346ed01f1a8f1d2baa8ef1Jamie Gennis            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
95d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
96698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            SurfaceComposerClient::closeGlobalTransaction();
97d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
98d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            sp<ANativeWindow> window = mSurfaceControl->getSurface();
991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
100d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    window.get(), NULL);
101d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
102d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGLint pbufferAttribs[] = {
103d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_WIDTH, getSurfaceWidth(),
104d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_HEIGHT, getSurfaceHeight(),
105d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_NONE };
106d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
1071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
108d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    pbufferAttribs);
109d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
110d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
111d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
112d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
1131876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
114d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                getContextAttribs());
115d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
116d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
117d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
118d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
119d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                mEglContext));
120d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
121d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
122d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint w, h;
123d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
124d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
125d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
126d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
127d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglSurfaceWidth", w);
128d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglSurfaceHeight", h);
129d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
130d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glViewport(0, 0, w, h);
131d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
132d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
133d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
134d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void TearDown() {
1359abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        // Display the result
136d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
137d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglSwapBuffers(mEglDisplay, mEglSurface);
138d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            sleep(mDisplaySecs);
139d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
140d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
141d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mComposerClient != NULL) {
142d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mComposerClient->dispose();
143d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
144d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglContext != EGL_NO_CONTEXT) {
145d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglDestroyContext(mEglDisplay, mEglContext);
146d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
147d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglSurface != EGL_NO_SURFACE) {
148d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglDestroySurface(mEglDisplay, mEglSurface);
149d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
150d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglDisplay != EGL_NO_DISPLAY) {
151d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
152d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    EGL_NO_CONTEXT);
153d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglTerminate(mEglDisplay);
154d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
155d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
156fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
157fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        const ::testing::TestInfo* const testInfo =
158fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            ::testing::UnitTest::GetInstance()->current_test_info();
159fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        ALOGV("End test:   %s.%s", testInfo->test_case_name(),
160fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                testInfo->name());
161d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
162d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
163d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint const* getConfigAttribs() {
164d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        static EGLint sDefaultConfigAttribs[] = {
165d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
166d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
167d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_RED_SIZE, 8,
168d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_GREEN_SIZE, 8,
169d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_BLUE_SIZE, 8,
170d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_ALPHA_SIZE, 8,
171d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_DEPTH_SIZE, 16,
172d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_STENCIL_SIZE, 8,
173d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_NONE };
174d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
175d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        return sDefaultConfigAttribs;
176d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
177d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
178d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint const* getContextAttribs() {
179d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        static EGLint sDefaultContextAttribs[] = {
180d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_CONTEXT_CLIENT_VERSION, 2,
181d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_NONE };
182d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
183d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        return sDefaultContextAttribs;
184d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
185d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
186d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint getSurfaceWidth() {
187c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis        return 512;
188d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
189d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
190d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint getSurfaceHeight() {
191c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis        return 512;
192d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
193d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
194d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ::testing::AssertionResult checkPixel(int x, int y, int r,
195824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis            int g, int b, int a, int tolerance=2) {
196d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLubyte pixel[4];
197d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        String8 msg;
198d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
199d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLenum err = glGetError();
200d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (err != GL_NO_ERROR) {
201d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("error reading pixel: %#x", err);
202d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            while ((err = glGetError()) != GL_NO_ERROR) {
203d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += String8::format(", %#x", err);
204d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
205d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            fprintf(stderr, "pixel check failure: %s\n", msg.string());
206d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionFailure(
207d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    ::testing::Message(msg.string()));
208d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
209824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
210d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("r(%d isn't %d)", pixel[0], r);
211d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
212824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
213d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
214d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
215d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
216d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("g(%d isn't %d)", pixel[1], g);
217d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
218824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
219d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
220d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
221d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
222d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("b(%d isn't %d)", pixel[2], b);
223d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
224824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
225d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
226d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
227d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
228d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("a(%d isn't %d)", pixel[3], a);
229d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
230d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (!msg.isEmpty()) {
231d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            fprintf(stderr, "pixel check failure: %s\n", msg.string());
232d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionFailure(
233d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    ::testing::Message(msg.string()));
234d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
235d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionSuccess();
236d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
237d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
238d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
239d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int mDisplaySecs;
240d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceComposerClient> mComposerClient;
241d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceControl> mSurfaceControl;
242d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
243d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLDisplay mEglDisplay;
244d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLSurface mEglSurface;
245d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLContext mEglContext;
2461876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EGLConfig  mGlConfig;
247d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis};
248d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
24974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic void loadShader(GLenum shaderType, const char* pSource,
25074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLuint* outShader) {
25174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLuint shader = glCreateShader(shaderType);
25274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
25374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    if (shader) {
25474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glShaderSource(shader, 1, &pSource, NULL);
25574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
25674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glCompileShader(shader);
25774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
25874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint compiled = 0;
25974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
26074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
26174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        if (!compiled) {
26274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            GLint infoLen = 0;
26374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
26474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
26574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            if (infoLen) {
26674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                char* buf = (char*) malloc(infoLen);
26774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                if (buf) {
26874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
26974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    printf("Shader compile log:\n%s\n", buf);
27074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    free(buf);
27174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    FAIL();
27274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                }
27374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            } else {
27474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                char* buf = (char*) malloc(0x1000);
27574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                if (buf) {
27674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    glGetShaderInfoLog(shader, 0x1000, NULL, buf);
27774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    printf("Shader compile log:\n%s\n", buf);
27874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    free(buf);
27974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    FAIL();
28074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                }
28174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            }
28274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glDeleteShader(shader);
28374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            shader = 0;
28474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
28574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
28674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(shader != 0);
28774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    *outShader = shader;
28874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
28974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
29074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic void createProgram(const char* pVertexSource,
29174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        const char* pFragmentSource, GLuint* outPgm) {
29274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLuint vertexShader, fragmentShader;
29374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    {
29474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        SCOPED_TRACE("compiling vertex shader");
29574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource,
29674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                &vertexShader));
29774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
29874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    {
29974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        SCOPED_TRACE("compiling fragment shader");
30074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource,
30174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                &fragmentShader));
30274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
30374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
30474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLuint program = glCreateProgram();
30574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
30674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    if (program) {
30774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glAttachShader(program, vertexShader);
30874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
30974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glAttachShader(program, fragmentShader);
31074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
31174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glLinkProgram(program);
31274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint linkStatus = GL_FALSE;
31374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
31474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        if (linkStatus != GL_TRUE) {
31574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            GLint bufLength = 0;
31674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
31774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            if (bufLength) {
31874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                char* buf = (char*) malloc(bufLength);
31974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                if (buf) {
32074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    glGetProgramInfoLog(program, bufLength, NULL, buf);
32174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    printf("Program link log:\n%s\n", buf);
32274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    free(buf);
32374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    FAIL();
32474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                }
32574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            }
32674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glDeleteProgram(program);
32774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            program = 0;
32874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
32974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
33074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glDeleteShader(vertexShader);
33174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glDeleteShader(fragmentShader);
33274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(program != 0);
33374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    *outPgm = program;
33474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
33574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
33674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic int abs(int value) {
33774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    return value > 0 ? value : -value;
33874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
33974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
34074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
341d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// XXX: Code above this point should live elsewhere
342d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
343d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisclass SurfaceTextureGLTest : public GLTest {
344d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisprotected:
34579e3125d56cca5aba88097b5ccd4f1e128bc8141Jamie Gennis    enum { TEX_ID = 123 };
346d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
347d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void SetUp() {
348d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLTest::SetUp();
349d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mST = new SurfaceTexture(TEX_ID);
350d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mSTC = new SurfaceTextureClient(mST);
351d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mANW = mSTC;
35274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mTextureRenderer = new TextureRenderer(TEX_ID, mST);
35374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp());
354d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
355d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
3562640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis    virtual void TearDown() {
3572640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        mANW.clear();
3582640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        mSTC.clear();
3592640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        mST.clear();
3602640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        GLTest::TearDown();
3612640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis    }
3622640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis
363d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    void drawTexture() {
36474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mTextureRenderer->drawTexture();
36574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
366d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
36774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    class TextureRenderer: public RefBase {
36874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    public:
36974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        TextureRenderer(GLuint texName, const sp<SurfaceTexture>& st):
37074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mTexName(texName),
37174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mST(st) {
37274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
373d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
37474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        void SetUp() {
37574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            const char vsrc[] =
37674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "attribute vec4 vPosition;\n"
37774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "varying vec2 texCoords;\n"
37874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "uniform mat4 texMatrix;\n"
37974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "void main() {\n"
38074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
38174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
38274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "  gl_Position = vPosition;\n"
38374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "}\n";
38474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
38574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            const char fsrc[] =
38674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "#extension GL_OES_EGL_image_external : require\n"
38774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "precision mediump float;\n"
38874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "uniform samplerExternalOES texSampler;\n"
38974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "varying vec2 texCoords;\n"
39074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "void main() {\n"
39174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "  gl_FragColor = texture2D(texSampler, texCoords);\n"
39274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "}\n";
39374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
39474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            {
39574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                SCOPED_TRACE("creating shader program");
39674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                ASSERT_NO_FATAL_FAILURE(createProgram(vsrc, fsrc, &mPgm));
39774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            }
3981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
39974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
40074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
40174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_NE(-1, mPositionHandle);
40274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
40374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
40474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_NE(-1, mTexSamplerHandle);
40574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
40674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
40774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_NE(-1, mTexMatrixHandle);
40874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
409d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
41074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        // drawTexture draws the SurfaceTexture over the entire GL viewport.
41174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        void drawTexture() {
41274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            const GLfloat triangleVertices[] = {
41374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                -1.0f, 1.0f,
41474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                -1.0f, -1.0f,
41574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                1.0f, -1.0f,
41674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                1.0f, 1.0f,
41774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            };
41874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
41974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
42074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    triangleVertices);
42174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
42274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glEnableVertexAttribArray(mPositionHandle);
42374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
42474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
42574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glUseProgram(mPgm);
42674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glUniform1i(mTexSamplerHandle, 0);
42774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
42874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName);
42974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
43074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
43174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
43274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            // they're setting the defautls for that target, but when hacking
43374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            // things to use GL_TEXTURE_2D they are needed to achieve the same
43474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            // behavior.
43574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
43674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    GL_LINEAR);
43774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
43874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
43974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    GL_LINEAR);
44074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
44174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
44274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    GL_CLAMP_TO_EDGE);
44374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
44474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
44574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    GL_CLAMP_TO_EDGE);
44674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
44774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
44874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            GLfloat texMatrix[16];
44974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mST->getTransformMatrix(texMatrix);
45074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
45174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
45274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
45374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
45474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
45574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
45674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLuint mTexName;
45774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        sp<SurfaceTexture> mST;
45874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLuint mPgm;
45974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint mPositionHandle;
46074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint mTexSamplerHandle;
46174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint mTexMatrixHandle;
46274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    };
463d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
464dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    class FrameWaiter : public SurfaceTexture::FrameAvailableListener {
465dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    public:
466dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        FrameWaiter():
467dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                mPendingFrames(0) {
468dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
469dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
470dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        void waitForFrame() {
471dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            Mutex::Autolock lock(mMutex);
472dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            while (mPendingFrames == 0) {
473dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                mCondition.wait(mMutex);
474dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            }
475dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            mPendingFrames--;
476dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
477dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
478dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        virtual void onFrameAvailable() {
479dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            Mutex::Autolock lock(mMutex);
480dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            mPendingFrames++;
481dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            mCondition.signal();
482dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
483dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
484dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        int mPendingFrames;
485dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        Mutex mMutex;
486dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        Condition mCondition;
487dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    };
488dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
4899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // Note that SurfaceTexture will lose the notifications
4909abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // onBuffersReleased and onFrameAvailable as there is currently
4919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // no way to forward the events.  This DisconnectWaiter will not let the
4929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // disconnect finish until finishDisconnect() is called.  It will
4939abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // also block until a disconnect is called
4949abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    class DisconnectWaiter : public BufferQueue::ConsumerListener {
4959abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    public:
4969abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        DisconnectWaiter () :
4979abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mWaitForDisconnect(false),
4989abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mPendingFrames(0) {
4999abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
5009abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
5019abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        void waitForFrame() {
5029abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            Mutex::Autolock lock(mMutex);
5039abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            while (mPendingFrames == 0) {
5049abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                mFrameCondition.wait(mMutex);
5059abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            }
5069abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mPendingFrames--;
5079abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
5089abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
5099abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        virtual void onFrameAvailable() {
5109abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            Mutex::Autolock lock(mMutex);
5119abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mPendingFrames++;
5129abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mFrameCondition.signal();
5139abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
5149abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
5159abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        virtual void onBuffersReleased() {
5169abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            Mutex::Autolock lock(mMutex);
5179abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            while (!mWaitForDisconnect) {
5189abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                mDisconnectCondition.wait(mMutex);
5199abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            }
5209abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
5219abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
5229abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        void finishDisconnect() {
5239abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            Mutex::Autolock lock(mMutex);
5249abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mWaitForDisconnect = true;
5259abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mDisconnectCondition.signal();
5269abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
5279abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
5289abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    private:
5299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        Mutex mMutex;
5309abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
5319abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        bool mWaitForDisconnect;
5329abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        Condition mDisconnectCondition;
5339abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
5349abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        int mPendingFrames;
5359abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        Condition mFrameCondition;
5369abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    };
5379abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
538d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceTexture> mST;
539d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceTextureClient> mSTC;
540d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<ANativeWindow> mANW;
54174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<TextureRenderer> mTextureRenderer;
542d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis};
543d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
544d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// Fill a YV12 buffer with a multi-colored checkerboard pattern
545d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisvoid fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
546d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int blockWidth = w > 16 ? w / 16 : 1;
547d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int blockHeight = h > 16 ? h / 16 : 1;
548d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int yuvTexOffsetY = 0;
549d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideY = stride;
550d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetV = yuvTexStrideY * h;
551d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
552d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
553d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideU = yuvTexStrideV;
554d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int x = 0; x < w; x++) {
555d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        for (int y = 0; y < h; y++) {
556d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            int parityX = (x / blockWidth) & 1;
557d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            int parityY = (y / blockHeight) & 1;
558d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
559d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
560d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (x < w / 2 && y < h / 2) {
561d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
562d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                if (x * 2 < w / 2 && y * 2 < h / 2) {
563d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
564d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
565d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
566d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
567d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        intensity;
568d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                }
569d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
570d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
571d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
572d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
573d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
574d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// Fill a YV12 buffer with red outside a given rectangle and green inside it.
575d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisvoid fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
576d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const android_native_rect_t& rect) {
577d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int yuvTexOffsetY = 0;
578d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideY = stride;
579d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetV = yuvTexStrideY * h;
580d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
581d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
582d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideU = yuvTexStrideV;
583d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int x = 0; x < w; x++) {
584d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        for (int y = 0; y < h; y++) {
585d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            bool inside = rect.left <= x && x < rect.right &&
586d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    rect.top <= y && y < rect.bottom;
587d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
588d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (x < w / 2 && y < h / 2) {
589d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                bool inside = rect.left <= 2*x && 2*x < rect.right &&
590d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        rect.top <= 2*y && 2*y < rect.bottom;
591d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
592d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
593d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        inside ? 16 : 255;
594d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
595d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
596d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
597d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
598d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
5991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennisvoid fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
6001876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const size_t PIXEL_SIZE = 4;
6011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    for (int x = 0; x < w; x++) {
6021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        for (int y = 0; y < h; y++) {
6031876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            off_t offset = (y * stride + x) * PIXEL_SIZE;
6041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            for (int c = 0; c < 4; c++) {
6051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                int parityX = (x / (1 << (c+2))) & 1;
6061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                int parityY = (y / (1 << (c+2))) & 1;
6071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
6081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            }
6091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        }
6101876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    }
6111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
6121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
613fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisvoid fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
614fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        uint8_t g, uint8_t b, uint8_t a) {
615fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    const size_t PIXEL_SIZE = 4;
616fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    for (int y = 0; y < h; y++) {
617fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        for (int x = 0; x < h; x++) {
618fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            off_t offset = (y * stride + x) * PIXEL_SIZE;
619fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            buf[offset + 0] = r;
620fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            buf[offset + 1] = g;
621fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            buf[offset + 2] = b;
622fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            buf[offset + 3] = a;
623fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        }
624fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    }
625fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis}
626fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
627ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// Produce a single RGBA8 frame by filling a buffer with a checkerboard pattern
628ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// using the CPU.  This assumes that the ANativeWindow is already configured to
629ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// allow this to be done (e.g. the format is set to RGBA8).
630ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis//
631ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// Calls to this function should be wrapped in an ASSERT_NO_FATAL_FAILURE().
632ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisvoid produceOneRGBA8Frame(const sp<ANativeWindow>& anw) {
633ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    android_native_buffer_t* anb;
634ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &anb));
635ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_TRUE(anb != NULL);
636ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
637ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
638ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf->getNativeBuffer()));
639ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
640ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    uint8_t* img = NULL;
641ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
642ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis            (void**)(&img)));
643ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    fillRGBA8Buffer(img, buf->getWidth(), buf->getHeight(), buf->getStride());
644ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(NO_ERROR, buf->unlock());
645ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf->getNativeBuffer()));
646ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis}
647ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
648d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
6491876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
6501876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
651d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
652d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
6531876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
654d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
655d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
656d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
657697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    ANativeWindowBuffer* anb;
658d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
659d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_TRUE(anb != NULL);
660d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
661d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
662d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
663d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
664d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    // Fill the buffer with the a checkerboard pattern
665d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    uint8_t* img = NULL;
666d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
6671876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
668d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->unlock();
669d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
670d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
671d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    mST->updateTexImage();
672d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
673d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
674d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
675d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
676c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
677d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    drawTexture();
678d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
679d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
680d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
681c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(63, 65,   0, 133,   0, 255));
682c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255));
683d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
684c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255));
685c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255));
686c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(52, 51,  98, 255,  73, 255));
687d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255));
688c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(31,  9, 107,  24,  87, 255));
689d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255));
690d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255));
691d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
692d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
693d05bb2ed4c99894965134994cf23c9e47274f56eJamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
6941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
6951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
696d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
697d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
6981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
699d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
700d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
701d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
702697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    ANativeWindowBuffer* anb;
703d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
704d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_TRUE(anb != NULL);
705d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
706d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
707d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
708d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
709d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    // Fill the buffer with the a checkerboard pattern
710d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    uint8_t* img = NULL;
711d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
7121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
713d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->unlock();
714d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
715d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
716d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    mST->updateTexImage();
717d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
718d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
719d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
720d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
721c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
722d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    drawTexture();
723d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
724d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0,   0, 133,   0, 255));
725d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 255, 127, 255, 255));
726d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
727d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
728d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
729d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255));
730d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255));
731d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255));
732d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
733d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255));
734d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255));
735d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
736d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
737d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
738d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
7391876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
7401876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
741d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
742d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
7431876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
744d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
745d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
746d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
747d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    android_native_rect_t crops[] = {
748d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {4, 6, 22, 36},
749d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {0, 6, 22, 36},
750d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {4, 0, 22, 36},
7511876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        {4, 6, texWidth, 36},
7521876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        {4, 6, 22, texHeight},
753d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    };
754d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
755d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int i = 0; i < 5; i++) {
756d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const android_native_rect_t& crop(crops[i]);
7576f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
7586f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                crop.left, crop.top, crop.right, crop.bottom).string());
759d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
760d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
761d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
762697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer* anb;
763d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
764d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_TRUE(anb != NULL);
765d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
766d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
7676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
7686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                buf->getNativeBuffer()));
769d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
770d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        uint8_t* img = NULL;
771d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
7721876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
773d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        buf->unlock();
7746f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
7756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                buf->getNativeBuffer()));
776d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
777d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mST->updateTexImage();
778d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
779d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glClearColor(0.2, 0.2, 0.2, 0.2);
780d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
781d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
782c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis        glViewport(0, 0, 64, 64);
783d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        drawTexture();
784d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
785d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
786d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
787d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
788d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
789d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
790d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
791d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
792d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
793d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
794d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
795d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
796d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
797d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
798d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
799d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
800dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis// This test is intended to catch synchronization bugs between the CPU-written
801dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis// and GPU-read buffers.
802dfcff4b4ef8b602ba485848b394b16d14847821eJamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
803dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    enum { texWidth = 16 };
804dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    enum { texHeight = 16 };
805dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    enum { numFrames = 1024 };
806dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
807dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true));
808dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    ASSERT_EQ(NO_ERROR, mST->setBufferCountServer(2));
809dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
810dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
811dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
812dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            GRALLOC_USAGE_SW_WRITE_OFTEN));
813dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
814dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    struct TestPixel {
815dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        int x;
816dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        int y;
817dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    };
818dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    const TestPixel testPixels[] = {
819dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        {  4, 11 },
820dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        { 12, 14 },
821dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        {  7,  2 },
822dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    };
823dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
824dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
825dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    class ProducerThread : public Thread {
826dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    public:
8276f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ProducerThread(const sp<ANativeWindow>& anw,
8286f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                const TestPixel* testPixels):
829dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                mANW(anw),
830dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                mTestPixels(testPixels) {
831dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
832dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
833dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        virtual ~ProducerThread() {
834dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
835dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
836dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        virtual bool threadLoop() {
837dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            for (int i = 0; i < numFrames; i++) {
838dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                ANativeWindowBuffer* anb;
839dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
840dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    return false;
841dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
842dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                if (anb == NULL) {
843dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    return false;
844dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
845dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
846dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
847dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                if (mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())
848dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        != NO_ERROR) {
849dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    return false;
850dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
851dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
852dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                const int yuvTexOffsetY = 0;
853dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int stride = buf->getStride();
854dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexStrideY = stride;
855dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexOffsetV = yuvTexStrideY * texHeight;
856dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
857dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
858dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexStrideU = yuvTexStrideV;
859dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
860dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                uint8_t* img = NULL;
861dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
862dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
863dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // Gray out all the test pixels first, so we're more likely to
864dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // see a failure if GL is still texturing from the buffer we
865dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // just dequeued.
866dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                for (int j = 0; j < numTestPixels; j++) {
867dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    int x = mTestPixels[j].x;
868dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    int y = mTestPixels[j].y;
869dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    uint8_t value = 128;
870dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    img[y*stride + x] = value;
871dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
872dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
873dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // Fill the buffer with gray.
874dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                for (int y = 0; y < texHeight; y++) {
875dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    for (int x = 0; x < texWidth; x++) {
876dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
877dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
878dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
879dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    }
880dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
881dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
882dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // Set the test pixels to either white or black.
883dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                for (int j = 0; j < numTestPixels; j++) {
884dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    int x = mTestPixels[j].x;
885dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    int y = mTestPixels[j].y;
886dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    uint8_t value = 0;
887dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    if (j == (i % numTestPixels)) {
888dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        value = 255;
889dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    }
890dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    img[y*stride + x] = value;
891dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
892dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
893dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                buf->unlock();
894dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())
895dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        != NO_ERROR) {
896dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    return false;
897dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
898dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            }
899dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            return false;
900dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
901dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
902dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        sp<ANativeWindow> mANW;
903dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        const TestPixel* mTestPixels;
904dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    };
905dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
906dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
907dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    mST->setFrameAvailableListener(fw);
908dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
909dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    sp<Thread> pt(new ProducerThread(mANW, testPixels));
910dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    pt->run();
911dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
912dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    glViewport(0, 0, texWidth, texHeight);
913dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
914dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
915dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
916dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
917dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    // We wait for the first two frames up front so that the producer will be
918dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    // likely to dequeue the buffer that's currently being textured from.
919dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    fw->waitForFrame();
920dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    fw->waitForFrame();
921dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
922dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    for (int i = 0; i < numFrames; i++) {
923dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        SCOPED_TRACE(String8::format("frame %d", i).string());
924dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
925dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        // We must wait for each frame to come in because if we ever do an
926dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        // updateTexImage call that doesn't consume a newly available buffer
927dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        // then the producer and consumer will get out of sync, which will cause
928dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        // a deadlock.
929dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        if (i > 1) {
930dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            fw->waitForFrame();
931dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
932dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        mST->updateTexImage();
933dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        drawTexture();
934dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
935dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        for (int j = 0; j < numTestPixels; j++) {
936dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            int x = testPixels[j].x;
937dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            int y = testPixels[j].y;
938dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            uint8_t value = 0;
939dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            if (j == (i % numTestPixels)) {
940dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // We must y-invert the texture coords
941dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
942dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            } else {
943dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // We must y-invert the texture coords
944dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
945dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            }
946dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
947dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    }
948dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
949dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    pt->requestExitAndWait();
950dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis}
951dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
9521f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
9531876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
9541876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
9551876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
9561876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
9571876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
9581876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
9591876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
9601876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
961ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
9621876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
9631876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->updateTexImage();
9641876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
9651876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
9661876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
9671876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
968c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
9691876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
9701876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
9711876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
9721876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
973c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
974c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel( 0, 65,  35,  35,  35,  35));
9751876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
9761876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
9771f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(23, 65, 231,  35, 231,  35));
978c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(19, 40,  35, 231,  35,  35));
9791876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
9801876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
9811f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(37, 34,  35, 231, 231, 231));
9821876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
9831f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(37, 47, 231,  35, 231, 231));
9841f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(25, 38,  35,  35,  35,  35));
9851f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(49,  6,  35, 231,  35,  35));
9861876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
9871f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
9881f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(10,  6,  35,  35, 231, 231));
9891876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
9901f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(55, 28,  35,  35, 231,  35));
9911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
9921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
9931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
9941f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
9951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
9961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
9971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
9981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
9991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
10001876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
10011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
10021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1003ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
10041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
10051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->updateTexImage();
10061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
10071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
10081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
10091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1010c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
10111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
10121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
10131876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
10141876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
10151876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
10161876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
10171876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
10181876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
10191876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
10201876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
10211876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
10221876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
10231876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
10241876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
10251876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
10261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
10271876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
10281876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
10291876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
10301876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
10311876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
10321876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
10331876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
10341876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
10351876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
10369abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// Tests if SurfaceTexture and BufferQueue are robust enough
10379abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// to handle a special case where updateTexImage is called
10389abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// in the middle of disconnect.  This ordering is enforced
10399abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// by blocking in the disconnect callback.
10409abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel LamTEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
10419abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10429abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    class ProducerThread : public Thread {
10439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    public:
10449abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        ProducerThread(const sp<ANativeWindow>& anw):
10459abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                mANW(anw) {
10469abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
10479abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10489abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        virtual ~ProducerThread() {
10499abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
10509abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10519abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        virtual bool threadLoop() {
10529abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            ANativeWindowBuffer* anb;
10539abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10549abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL);
10559abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10569abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            for (int numFrames =0 ; numFrames < 2; numFrames ++) {
10579abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10589abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
10599abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                    return false;
10609abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                }
10619abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                if (anb == NULL) {
10629abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                    return false;
10639abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                }
10649abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                if (mANW->queueBuffer(mANW.get(), anb)
10659abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                        != NO_ERROR) {
10669abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                    return false;
10679abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                }
10689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            }
10699abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10709abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL);
10719abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10729abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            return false;
10739abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
10749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    private:
10769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        sp<ANativeWindow> mANW;
10779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    };
10789abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10799abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    ASSERT_EQ(OK, mST->setSynchronousMode(true));
10809abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10819abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    sp<DisconnectWaiter> dw(new DisconnectWaiter());
10829abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    mST->getBufferQueue()->consumerConnect(dw);
10839abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10849abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10859abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    sp<Thread> pt(new ProducerThread(mANW));
10869abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    pt->run();
10879abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // eat a frame so SurfaceTexture will own an at least one slot
10899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    dw->waitForFrame();
10909abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
10919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    dw->waitForFrame();
10939abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // Could fail here as SurfaceTexture thinks it still owns the slot
10949abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // but bufferQueue has released all slots
10959abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
10969abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
10979abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    dw->finishDisconnect();
10989abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam}
10999abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11009abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11019abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// This test ensures that the SurfaceTexture clears the mCurrentTexture
11029abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// when it is disconnected and reconnected.  Otherwise it will
11039abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// attempt to release a buffer that it does not owned
11049abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel LamTEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
11059abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    ASSERT_EQ(OK, mST->setSynchronousMode(true));
11069abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11079abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL);
11089abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11099abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    ANativeWindowBuffer *anb;
11109abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11119abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ (OK, mANW->dequeueBuffer(mANW.get(), &anb));
11129abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb));
11139abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11149abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ (OK, mANW->dequeueBuffer(mANW.get(), &anb));
11159abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb));
11169abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11179abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
11189abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
11199abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11209abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL);
11219abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL);
11229abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11239abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    ASSERT_EQ(OK, mST->setSynchronousMode(true));
11249abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11259abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ (OK, mANW->dequeueBuffer(mANW.get(), &anb));
11269abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb));
11279abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11289abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // Will fail here if mCurrentTexture is not cleared properly
11299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
11309abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam}
11319abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11326f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
11336f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    class ProducerThread : public Thread {
11346f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    public:
11356f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ProducerThread(const sp<ANativeWindow>& anw):
11366f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mANW(anw),
11376f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mDequeueError(NO_ERROR) {
11386f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
11396f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11406f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        virtual ~ProducerThread() {
11416f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
11426f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11436f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        virtual bool threadLoop() {
11446f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            Mutex::Autolock lock(mMutex);
11456f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            ANativeWindowBuffer* anb;
11466f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11476f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            // Frame 1
11486f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
11496f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
11506f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
11516f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            if (anb == NULL) {
11526f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
11536f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
11546f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            if (mANW->queueBuffer(mANW.get(), anb)
11556f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                    != NO_ERROR) {
11566f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
11576f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
11586f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11596f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            // Frame 2
11606f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
11616f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
11626f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
11636f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            if (anb == NULL) {
11646f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
11656f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
11666f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            if (mANW->queueBuffer(mANW.get(), anb)
11676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                    != NO_ERROR) {
11686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
11696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
11706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            // Frame 3 - error expected
11726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            mDequeueError = mANW->dequeueBuffer(mANW.get(), &anb);
11736f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            return false;
11746f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
11756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11766f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        status_t getDequeueError() {
11776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            Mutex::Autolock lock(mMutex);
11786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            return mDequeueError;
11796f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
11806f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11816f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    private:
11826f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        sp<ANativeWindow> mANW;
11836f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        status_t mDequeueError;
11846f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        Mutex mMutex;
11856f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    };
11866f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
11886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->setFrameAvailableListener(fw);
11896f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_EQ(OK, mST->setSynchronousMode(true));
11906f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_EQ(OK, mST->setBufferCountServer(2));
11916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11926f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    sp<Thread> pt(new ProducerThread(mANW));
11936f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    pt->run();
11946f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11956f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    fw->waitForFrame();
11966f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    fw->waitForFrame();
11976f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
11986f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
11996f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // block waiting for a buffer to become available.
12006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    usleep(100000);
12016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12026f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->abandon();
12036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12046f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    pt->requestExitAndWait();
12056f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_EQ(NO_INIT,
12066f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
12076f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis}
12086f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12096f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
12106f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    int texHeight = 16;
12116f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ANativeWindowBuffer* anb;
12126f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12136f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    GLint maxTextureSize;
12146f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
12156f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12166f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // make sure it works with small textures
12176f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->setDefaultBufferSize(16, texHeight);
12186f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
12196f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(16, anb->width);
12206f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(texHeight, anb->height);
12216f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
12226f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
12236f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12246f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // make sure it works with GL_MAX_TEXTURE_SIZE
12256f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->setDefaultBufferSize(maxTextureSize, texHeight);
12266f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
12276f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(maxTextureSize, anb->width);
12286f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(texHeight, anb->height);
12296f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
12306f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
12316f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12326f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // make sure it fails with GL_MAX_TEXTURE_SIZE+1
12336f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
12346f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
12356f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(maxTextureSize+1, anb->width);
12366f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(texHeight, anb->height);
12376f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
12386f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_NE(NO_ERROR, mST->updateTexImage());
12396f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis}
12406f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12416f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis/*
12426f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * This test fixture is for testing GL -> GL texture streaming.  It creates an
12436f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * EGLSurface and an EGLContext for the image producer to use.
12446f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis */
12456f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisclass SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
12466f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisprotected:
12476f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    SurfaceTextureGLToGLTest():
12486f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            mProducerEglSurface(EGL_NO_SURFACE),
12496f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            mProducerEglContext(EGL_NO_CONTEXT) {
12506f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
12516f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12526f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    virtual void SetUp() {
12536f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SurfaceTextureGLTest::SetUp();
12546f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
1255ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
12566f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mANW.get(), NULL);
12576f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
12586f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
12596f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
1260ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        mProducerEglContext = eglCreateContext(mEglDisplay, mGlConfig,
12616f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                EGL_NO_CONTEXT, getContextAttribs());
12626f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
12636f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
12646f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
12656f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12666f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    virtual void TearDown() {
12676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        if (mProducerEglContext != EGL_NO_CONTEXT) {
12686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            eglDestroyContext(mEglDisplay, mProducerEglContext);
12696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
12706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        if (mProducerEglSurface != EGL_NO_SURFACE) {
12716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            eglDestroySurface(mEglDisplay, mProducerEglSurface);
12726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
12736f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SurfaceTextureGLTest::TearDown();
12746f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
12756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12766f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EGLSurface mProducerEglSurface;
12776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EGLContext mProducerEglContext;
12786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis};
12796f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
12806f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
12811876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
12821876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
12831876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
12841876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->setDefaultBufferSize(texWidth, texHeight);
12851876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
12861876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    // Do the producer side of things
12876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
12886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            mProducerEglSurface, mProducerEglContext));
12891876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
12901876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
12916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // This is needed to ensure we pick up a buffer of the correct size.
12926f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
12931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
12941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
12951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
12961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
12971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glEnable(GL_SCISSOR_TEST);
12981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(4, 4, 4, 4);
12991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
13001876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
13011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(24, 48, 4, 4);
13031876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.0, 1.0, 0.0, 1.0);
13041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
13051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(37, 17, 4, 4);
13071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.0, 0.0, 1.0, 1.0);
13081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
13091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13106f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
13111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    // Do the consumer side of things
13131876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
13141876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglContext));
13151876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
13161876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13171876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glDisable(GL_SCISSOR_TEST);
13181876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13196f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->updateTexImage(); // Skip the first frame, which was empty
13201876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->updateTexImage();
13211876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13221876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
13231876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
13241876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1325c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
13261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
13271876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13281876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
13291876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
13301876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
13311876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
13321876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13331876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
13341876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
13351876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
13361876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
13371876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
13381876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
13391876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
13401876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
13411876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
13421876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
13431876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
13441876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
13451876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
13461876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
13471876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
13481876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
13491876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
13501876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
13516f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
1352fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    sp<GraphicBuffer> buffers[2];
1353fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
1354fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
1355fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mST->setFrameAvailableListener(fw);
13567b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1357e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // This test requires async mode to run on a single thread.
1358e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1359e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis            mProducerEglSurface, mProducerEglContext));
1360e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1361e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
1362e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
13637b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1364fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    for (int i = 0; i < 2; i++) {
13656f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        // Produce a frame
13666f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
13676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mProducerEglSurface, mProducerEglContext));
13686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
13696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
13706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        eglSwapBuffers(mEglDisplay, mProducerEglSurface);
13717b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
13726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        // Consume a frame
13736f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
13746f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mEglContext));
13756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
1376fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        fw->waitForFrame();
13776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        mST->updateTexImage();
13786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        buffers[i] = mST->getCurrentBuffer();
13796f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
13807b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
13816f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Destroy the GL texture object to release its ref on buffers[2].
13826f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    GLuint texID = TEX_ID;
13836f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    glDeleteTextures(1, &texID);
13847b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
13856f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Destroy the EGLSurface
13866f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
13876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1388fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mProducerEglSurface = EGL_NO_SURFACE;
13897b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1390fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    // This test should have the only reference to buffer 0.
13916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(1, buffers[0]->getStrongCount());
13927b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1393fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    // The SurfaceTexture should hold a single reference to buffer 1 in its
1394fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    // mCurrentBuffer member.  All of the references in the slots should have
1395fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    // been released.
1396fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    EXPECT_EQ(2, buffers[1]->getStrongCount());
13976f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis}
13987b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
13996f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
14006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    sp<GraphicBuffer> buffers[3];
14017b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1402fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
1403fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mST->setFrameAvailableListener(fw);
1404fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
1405e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // This test requires async mode to run on a single thread.
1406e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1407e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis            mProducerEglSurface, mProducerEglContext));
1408e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1409e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
1410e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
14117b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
14126f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    for (int i = 0; i < 3; i++) {
14136f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        // Produce a frame
14146f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
14156f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mProducerEglSurface, mProducerEglContext));
14166f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
14176f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
14186f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
14196f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
14207b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
14216f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        // Consume a frame
14226f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
14236f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mEglContext));
14246f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
1425fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        fw->waitForFrame();
14266f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
14276f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        buffers[i] = mST->getCurrentBuffer();
14286f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
14297b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
14306f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has
14316f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // on buffers[2].
14327b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis    mST->abandon();
14337b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
14346f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Destroy the GL texture object to release its ref on buffers[2].
14356f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    GLuint texID = TEX_ID;
14366f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    glDeleteTextures(1, &texID);
14377b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
14386f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Destroy the EGLSurface.
14396f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
14406f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1441fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mProducerEglSurface = EGL_NO_SURFACE;
14427b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
14436f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(1, buffers[0]->getStrongCount());
14446f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(1, buffers[1]->getStrongCount());
1445e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis
1446e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // Depending on how lazily the GL driver dequeues buffers, we may end up
1447e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // with either two or three total buffers.  If there are three, make sure
1448e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // the last one was properly down-ref'd.
1449e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    if (buffers[2] != buffers[0]) {
1450e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis        EXPECT_EQ(1, buffers[2]->getStrongCount());
1451e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    }
14527b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis}
14537b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
145459769469e4b9b2d8b12c020eb44b030b3927a50bJamie GennisTEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) {
145559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis    // This test requires 3 buffers to run on a single thread.
145659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis    mST->setBufferCountServer(3);
145759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis
145859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis    ASSERT_TRUE(mST->isSynchronousMode());
145959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis
146059769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis    for (int i = 0; i < 10; i++) {
146159769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        // Produce a frame
146259769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
146359769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis                mProducerEglSurface, mProducerEglContext));
146459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
146559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
146659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
146759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
146859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis
146959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        // Consume a frame
147059769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
147159769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis                mEglContext));
147259769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
147359769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
147459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis    }
147559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis
147659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis    ASSERT_TRUE(mST->isSynchronousMode());
14777b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis}
14787b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1479c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromUserSizedGLFilledBuffer) {
1480c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texWidth = 64 };
1481c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texHeight = 64 };
1482c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1483c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the user buffer size.
1484c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
1485c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1486c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the producer side of things
1487c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1488c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mProducerEglSurface, mProducerEglContext));
1489c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1490c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1491c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // This is needed to ensure we pick up a buffer of the correct size.
1492c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1493c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1494c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
1495c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1496c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1497c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glEnable(GL_SCISSOR_TEST);
1498c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glScissor(4, 4, 1, 1);
1499c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
1500c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1501c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1502c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1503c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1504c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the consumer side of things
1505c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
1506c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mEglContext));
1507c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1508c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1509c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glDisable(GL_SCISSOR_TEST);
1510c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1511c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->updateTexImage(); // Skip the first frame, which was empty
1512c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->updateTexImage();
1513c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1514c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
1515c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1516c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1517c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glViewport(0, 0, texWidth, texHeight);
1518c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    drawTexture();
1519c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1520c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
1521c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
1522c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
1523c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
1524c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1525c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 4,  4, 255,   0,   0, 255));
1526c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 5,  5, 153, 153, 153, 153));
1527c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 3,  3, 153, 153, 153, 153));
1528c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(45, 52, 153, 153, 153, 153));
1529c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(12, 36, 153, 153, 153, 153));
1530c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis}
1531c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1532c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedUserSizedGLFilledBuffer) {
1533c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texWidth = 64 };
1534c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texHeight = 16 };
1535c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1536c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the transform hint.
1537c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
1538c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1539c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the user buffer size.
1540c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
1541c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1542c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the producer side of things
1543c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1544c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mProducerEglSurface, mProducerEglContext));
1545c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1546c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1547c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // This is needed to ensure we pick up a buffer of the correct size and the
1548c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // new rotation hint.
1549c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1550c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1551c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
1552c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1553c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1554c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glEnable(GL_SCISSOR_TEST);
1555c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glScissor(24, 4, 1, 1);
1556c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
1557c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1558c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1559c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1560c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1561c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the consumer side of things
1562c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
1563c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mEglContext));
1564c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1565c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1566c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glDisable(GL_SCISSOR_TEST);
1567c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1568c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->updateTexImage(); // Skip the first frame, which was empty
1569c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->updateTexImage();
1570c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1571c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
1572c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1573c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1574c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glViewport(0, 0, texWidth, texHeight);
1575c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    drawTexture();
1576c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1577c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
1578c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
1579c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
1580c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
1581c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1582c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
1583c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
1584c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
1585c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
1586c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
1587c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis}
1588c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1589c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedGLFilledBuffer) {
1590c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texWidth = 64 };
1591c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texHeight = 16 };
1592c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1593c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the transform hint.
1594c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
1595c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1596c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the default buffer size.
1597c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->setDefaultBufferSize(texWidth, texHeight);
1598c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1599c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the producer side of things
1600c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1601c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mProducerEglSurface, mProducerEglContext));
1602c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1603c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1604c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // This is needed to ensure we pick up a buffer of the correct size and the
1605c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // new rotation hint.
1606c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1607c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1608c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
1609c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1610c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1611c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glEnable(GL_SCISSOR_TEST);
1612c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glScissor(24, 4, 1, 1);
1613c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
1614c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1615c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1616c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1617c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1618c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the consumer side of things
1619c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
1620c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mEglContext));
1621c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1622c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1623c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glDisable(GL_SCISSOR_TEST);
1624c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1625c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->updateTexImage(); // Skip the first frame, which was empty
1626c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->updateTexImage();
1627c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1628c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
1629c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1630c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1631c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glViewport(0, 0, texWidth, texHeight);
1632c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    drawTexture();
1633c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1634c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
1635c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
1636c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
1637c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
1638c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1639c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
1640c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
1641c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
1642c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
1643c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
1644c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis}
1645c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
16465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis/*
16476f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * This test fixture is for testing GL -> GL texture streaming from one thread
16486f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * to another.  It contains functionality to create a producer thread that will
16496f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * perform GL rendering to an ANativeWindow that feeds frames to a
16506f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * SurfaceTexture.  Additionally it supports interlocking the producer and
16516f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * consumer threads so that a specific sequence of calls can be
16526f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * deterministically created by the test.
16535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
16545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * The intended usage is as follows:
16555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
16565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * TEST_F(...) {
16575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     class PT : public ProducerThread {
16585451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *         virtual void render() {
16595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *             ...
16605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *             swapBuffers();
16615451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *         }
16625451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     };
16635451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
16645451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     runProducerThread(new PT());
16655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
16665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // The order of these calls will vary from test to test and may include
16675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // multiple frames and additional operations (e.g. GL rendering from the
16685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // texture).
16695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     fc->waitForFrame();
16705451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     mST->updateTexImage();
16715451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     fc->finishFrame();
16725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * }
16735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
16745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis */
16756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisclass SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
16765451d15ee209f29d64beea87583f7058dee69911Jamie Gennisprotected:
16775451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
16785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // ProducerThread is an abstract base class to simplify the creation of
16795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // OpenGL ES frame producer threads.
16805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class ProducerThread : public Thread {
16815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    public:
16825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual ~ProducerThread() {
16835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
16845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
16855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void setEglObjects(EGLDisplay producerEglDisplay,
16865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                EGLSurface producerEglSurface,
16875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                EGLContext producerEglContext) {
16885451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglDisplay = producerEglDisplay;
16895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglSurface = producerEglSurface;
16905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglContext = producerEglContext;
16915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
16925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
16935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual bool threadLoop() {
16945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface,
16955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                    mProducerEglSurface, mProducerEglContext);
16965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            render();
16975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
16985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                    EGL_NO_CONTEXT);
16995451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            return false;
17005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
17015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    protected:
17035451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() = 0;
17045451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17055451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void swapBuffers() {
17065451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface);
17075451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
17085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLDisplay mProducerEglDisplay;
17105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLSurface mProducerEglSurface;
17115451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLContext mProducerEglContext;
17125451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
17135451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // FrameCondition is a utility class for interlocking between the producer
17155451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // and consumer threads.  The FrameCondition object should be created and
17165451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // destroyed in the consumer thread only.  The consumer thread should set
17175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // the FrameCondition as the FrameAvailableListener of the SurfaceTexture,
17185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // and should call both waitForFrame and finishFrame once for each expected
17195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // frame.
17205451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    //
17215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // This interlocking relies on the fact that onFrameAvailable gets called
17225451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // synchronously from SurfaceTexture::queueBuffer.
17235451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class FrameCondition : public SurfaceTexture::FrameAvailableListener {
17245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    public:
17252640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        FrameCondition():
17262640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis                mFrameAvailable(false),
17272640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis                mFrameFinished(false) {
17282640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        }
17292640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis
17305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // waitForFrame waits for the next frame to arrive.  This should be
17315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // called from the consumer thread once for every frame expected by the
17325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // test.
17335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void waitForFrame() {
17345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
17356807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("+waitForFrame");
17362640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            while (!mFrameAvailable) {
17372640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis                mFrameAvailableCondition.wait(mMutex);
17382640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            }
17392640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            mFrameAvailable = false;
17406807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("-waitForFrame");
17415451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
17425451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // Allow the producer to return from its swapBuffers call and continue
17445451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // on to produce the next frame.  This should be called by the consumer
17455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // thread once for every frame expected by the test.
17465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void finishFrame() {
17475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
17486807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("+finishFrame");
17492640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            mFrameFinished = true;
17505451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mFrameFinishCondition.signal();
17516807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("-finishFrame");
17525451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
17535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // This should be called by SurfaceTexture on the producer thread.
17555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void onFrameAvailable() {
17565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
17576807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("+onFrameAvailable");
17582640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            mFrameAvailable = true;
17595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mFrameAvailableCondition.signal();
17602640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            while (!mFrameFinished) {
17612640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis                mFrameFinishCondition.wait(mMutex);
17622640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            }
17632640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            mFrameFinished = false;
17646807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("-onFrameAvailable");
17655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
17665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    protected:
17682640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        bool mFrameAvailable;
17692640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        bool mFrameFinished;
17702640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis
17715451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Mutex mMutex;
17725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Condition mFrameAvailableCondition;
17735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Condition mFrameFinishCondition;
17745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
17755451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17765451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    virtual void SetUp() {
17776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SurfaceTextureGLToGLTest::SetUp();
17785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC = new FrameCondition();
17795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mST->setFrameAvailableListener(mFC);
17805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
17815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    virtual void TearDown() {
17835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        if (mProducerThread != NULL) {
17845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerThread->requestExitAndWait();
17855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
17865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mProducerThread.clear();
17875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC.clear();
17886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SurfaceTextureGLToGLTest::TearDown();
17895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
17905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    void runProducerThread(const sp<ProducerThread> producerThread) {
17925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        ASSERT_TRUE(mProducerThread == NULL);
17935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mProducerThread = producerThread;
17945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        producerThread->setEglObjects(mEglDisplay, mProducerEglSurface,
17955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                mProducerEglContext);
17965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        producerThread->run();
17975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
17985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
17995451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    sp<ProducerThread> mProducerThread;
18005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    sp<FrameCondition> mFC;
18015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis};
18025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
18046f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        UpdateTexImageBeforeFrameFinishedCompletes) {
18055451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
18065451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
18075451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
18085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClear(GL_COLOR_BUFFER_BIT);
18095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            swapBuffers();
18105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
18115451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
18125451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18135451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
18145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18155451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->waitForFrame();
18165451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mST->updateTexImage();
18175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->finishFrame();
18185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
1820d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
18215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18226f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
18236f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        UpdateTexImageAfterFrameFinishedCompletes) {
18245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
18255451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
18265451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
18275451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClear(GL_COLOR_BUFFER_BIT);
18285451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            swapBuffers();
18295451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
18305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
18315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
18335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->waitForFrame();
18355451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->finishFrame();
18365451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mST->updateTexImage();
18375451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18385451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
18395451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
18405451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18416f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
18426f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
18435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    enum { NUM_ITERATIONS = 1024 };
18445451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
18465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
18475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            for (int i = 0; i < NUM_ITERATIONS; i++) {
18485451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
18495451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClear(GL_COLOR_BUFFER_BIT);
18506807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("+swapBuffers");
18515451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                swapBuffers();
18526807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("-swapBuffers");
18535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            }
18545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
18555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
18565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
18585451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS; i++) {
18605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->waitForFrame();
18616807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("+updateTexImage");
18625451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mST->updateTexImage();
18636807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("-updateTexImage");
18645451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->finishFrame();
18655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
18675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
18685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
18695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
18716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
18725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    enum { NUM_ITERATIONS = 1024 };
18735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
18755451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
18765451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            for (int i = 0; i < NUM_ITERATIONS; i++) {
18775451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
18785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClear(GL_COLOR_BUFFER_BIT);
18796807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("+swapBuffers");
18805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                swapBuffers();
18816807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("-swapBuffers");
18825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            }
18835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
18845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
18855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
18875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18885451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS; i++) {
18895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->waitForFrame();
18905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->finishFrame();
18916807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("+updateTexImage");
18925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mST->updateTexImage();
18936807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("-updateTexImage");
18945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
18965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
18975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
18985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
18996e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis// XXX: This test is disabled because it is currently hanging on some devices.
19006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
19016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
19026e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    enum { NUM_ITERATIONS = 64 };
19036e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19046e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    class PT : public ProducerThread {
19056e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        virtual void render() {
19066e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis            for (int i = 0; i < NUM_ITERATIONS; i++) {
19076e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
19086e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis                glClear(GL_COLOR_BUFFER_BIT);
19096807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("+swapBuffers");
19106e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis                swapBuffers();
19116807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("-swapBuffers");
19126e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis            }
19136e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        }
19146e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    };
19156e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19166e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    ASSERT_EQ(OK, mST->setSynchronousMode(true));
19176e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    ASSERT_EQ(OK, mST->setBufferCountServer(2));
19186e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19196e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    runProducerThread(new PT());
19206e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19216e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Allow three frames to be rendered and queued before starting the
19226e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // rendering in this thread.  For the latter two frames we don't call
19236e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // updateTexImage so the next dequeue from the producer thread will block
19246e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // waiting for a frame to become available.
19256e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->waitForFrame();
19266e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->finishFrame();
19276e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19286e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // We must call updateTexImage to consume the first frame so that the
19296e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // SurfaceTexture is able to reduce the buffer count to 2.  This is because
19306e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // the GL driver may dequeue a buffer when the EGLSurface is created, and
19316e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // that happens before we call setBufferCountServer.  It's possible that the
19326e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // driver does not dequeue a buffer at EGLSurface creation time, so we
19336e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // cannot rely on this to cause the second dequeueBuffer call to block.
19346e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mST->updateTexImage();
19356e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19366e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->waitForFrame();
19376e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->finishFrame();
19386e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->waitForFrame();
19396e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->finishFrame();
19406e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19416e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
19426e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // block waiting for a buffer to become available.
19436e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    usleep(100000);
19446e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19456e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Render and present a number of images.  This thread should not be blocked
19466e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // by the fact that the producer thread is blocking in dequeue.
19476e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS; i++) {
19486e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
19496e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        eglSwapBuffers(mEglDisplay, mEglSurface);
19506e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    }
19516e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19526e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Consume the two pending buffers to unblock the producer thread.
19536e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mST->updateTexImage();
19546e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mST->updateTexImage();
19556e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
19566e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Consume the remaining buffers from the producer thread.
19576e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS-3; i++) {
19586e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        mFC->waitForFrame();
19596e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        mFC->finishFrame();
19606807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("+updateTexImage");
19616e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        mST->updateTexImage();
19626807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("-updateTexImage");
19636e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    }
19646e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis}
19656e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
1966fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisclass SurfaceTextureFBOTest : public SurfaceTextureGLTest {
1967fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisprotected:
1968fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
1969fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    virtual void SetUp() {
1970fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        SurfaceTextureGLTest::SetUp();
1971fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
1972fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glGenFramebuffers(1, &mFbo);
1973fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
1974fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
1975fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glGenTextures(1, &mFboTex);
1976fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glBindTexture(GL_TEXTURE_2D, mFboTex);
1977fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(),
1978fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1979fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glBindTexture(GL_TEXTURE_2D, 0);
1980fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
1981fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
1982fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
1983fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1984fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                GL_TEXTURE_2D, mFboTex, 0);
1985fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glBindFramebuffer(GL_FRAMEBUFFER, 0);
1986fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
1987fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    }
1988fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
1989fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    virtual void TearDown() {
1990fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        SurfaceTextureGLTest::TearDown();
1991fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
1992fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glDeleteTextures(1, &mFboTex);
1993fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glDeleteFramebuffers(1, &mFbo);
1994fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    }
1995fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
1996fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    GLuint mFbo;
1997fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    GLuint mFboTex;
1998fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis};
1999fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2000fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis// This test is intended to verify that proper synchronization is done when
2001fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis// rendering into an FBO.
2002fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie GennisTEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
2003fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    const int texWidth = 64;
2004fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    const int texHeight = 64;
2005fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2006fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
2007fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
2008fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
2009fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
2010fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2011fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    android_native_buffer_t* anb;
2012fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
2013fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_TRUE(anb != NULL);
2014fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2015fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2016fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
2017fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2018fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    // Fill the buffer with green
2019fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    uint8_t* img = NULL;
2020fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2021fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
2022fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            0, 255);
2023fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    buf->unlock();
2024fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
2025fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2026fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
2027fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2028fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
2029fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    drawTexture();
2030fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    glBindFramebuffer(GL_FRAMEBUFFER, 0);
2031fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2032fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    for (int i = 0; i < 4; i++) {
2033fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        SCOPED_TRACE(String8::format("frame %d", i).string());
2034fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2035fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
2036fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_TRUE(anb != NULL);
2037fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2038fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        buf = new GraphicBuffer(anb, false);
2039fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
2040fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                buf->getNativeBuffer()));
2041fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2042fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        // Fill the buffer with red
2043fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
2044fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                (void**)(&img)));
2045fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
2046fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                0, 255);
2047fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, buf->unlock());
2048fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
2049fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                buf->getNativeBuffer()));
2050fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2051fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
2052fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2053fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        drawTexture();
2054fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2055fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
2056fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    }
2057fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2058fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
2059fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2060fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
2061fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis}
2062fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2063ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisclass SurfaceTextureMultiContextGLTest : public SurfaceTextureGLTest {
2064ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisprotected:
206574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    enum { SECOND_TEX_ID = 123 };
206674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    enum { THIRD_TEX_ID = 456 };
206774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
2068ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    SurfaceTextureMultiContextGLTest():
2069ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis            mSecondEglContext(EGL_NO_CONTEXT) {
2070ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    }
2071ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2072ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    virtual void SetUp() {
2073ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        SurfaceTextureGLTest::SetUp();
2074ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
207574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        // Set up the secondary context and texture renderer.
2076ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        mSecondEglContext = eglCreateContext(mEglDisplay, mGlConfig,
2077ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis                EGL_NO_CONTEXT, getContextAttribs());
2078ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
2079ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mSecondEglContext);
208074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
208174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
208274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mSecondEglContext));
208374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
208474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mSecondTextureRenderer = new TextureRenderer(SECOND_TEX_ID, mST);
208574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(mSecondTextureRenderer->SetUp());
208674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
208774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        // Set up the tertiary context and texture renderer.
208874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mThirdEglContext = eglCreateContext(mEglDisplay, mGlConfig,
208974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                EGL_NO_CONTEXT, getContextAttribs());
209074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
209174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mThirdEglContext);
209274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
209374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
209474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mThirdEglContext));
209574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
209674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mThirdTextureRenderer = new TextureRenderer(THIRD_TEX_ID, mST);
209774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(mThirdTextureRenderer->SetUp());
209874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
209974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        // Switch back to the primary context to start the tests.
210074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
210174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mEglContext));
2102ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    }
2103ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2104ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    virtual void TearDown() {
210574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        if (mThirdEglContext != EGL_NO_CONTEXT) {
210674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            eglDestroyContext(mEglDisplay, mThirdEglContext);
210774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
2108ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        if (mSecondEglContext != EGL_NO_CONTEXT) {
2109ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis            eglDestroyContext(mEglDisplay, mSecondEglContext);
2110ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        }
2111ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        SurfaceTextureGLTest::TearDown();
2112ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    }
2113ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2114ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    EGLContext mSecondEglContext;
211574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<TextureRenderer> mSecondTextureRenderer;
211674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
211774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EGLContext mThirdEglContext;
211874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<TextureRenderer> mThirdTextureRenderer;
2119ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis};
2120ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2121ce561372186c7549a8a5fe996ac5965cda087007Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, UpdateFromMultipleContextsFails) {
2122ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
2123ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    mST->setFrameAvailableListener(fw);
2124ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2125ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
2126ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2127ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    // Latch the texture contents on the primary context.
212874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
212974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
2130ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2131ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    // Attempt to latch the texture on the secondary context.
213274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
213374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
213474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
213574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
213674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
213774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
213874bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextSucceeds) {
213974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
214074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
214174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
214274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
214374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
214474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
214574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
214674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
214774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
214874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
214974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
215074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
215174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Check that the GL texture was deleted.
215274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
215374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
215474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
215574bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
215674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        DetachFromContextSucceedsAfterProducerDisconnect) {
215774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
215874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
215974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
216074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
216174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
216274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
216374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
216474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
216574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
216674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
216774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
216874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
216974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
217074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Check that the GL texture was deleted.
217174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
217274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
217374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
217474bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenAbandoned) {
217574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
217674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
217774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
217874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
217974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
218074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
218174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
218274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
218374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
218474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to detach from the primary context.
218574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->abandon();
218674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(NO_INIT, mST->detachFromContext());
218774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
218874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
218974bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenDetached) {
219074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
219174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
219274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
219374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
219474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
219574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
219674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
219774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
219874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
219974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
220074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
220174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
220274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to detach from the primary context again.
220374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
220474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
220574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
220674bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoDisplay) {
220774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
220874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
220974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
221074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
221174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
221274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
221374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
221474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
221574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
221674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Make there be no current display.
221774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
221874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            EGL_NO_CONTEXT));
221974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
222074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
222174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to detach from the primary context.
222274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
222374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
222474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
222574bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoContext) {
222674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
222774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
222874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
222974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
223074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
223174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
223274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
223374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
223474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
223574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Make current context be incorrect.
223674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
2237ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis            mSecondEglContext));
2238ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
223974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
224074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to detach from the primary context.
224174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
224274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
224374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
224474bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, UpdateTexImageFailsWhenDetached) {
224574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
224674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
224774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
224874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
224974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
225074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
225174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
225274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
225374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to latch the texture contents on the primary context.
225474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
225574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
225674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
225774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
225874bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceeds) {
225974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
226074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
226174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
226274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
226374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
226474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
226574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
226674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
226774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
226874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
226974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
227074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
227174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
227274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
227374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
227474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
227574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
227674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
227774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
227874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
227974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(SECOND_TEX_ID, texBinding);
228074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
228174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the secondary context.
228274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
228374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
228474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
228574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mSecondTextureRenderer->drawTexture();
228674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
228774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
228874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
228974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
229074bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
229174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        AttachToContextSucceedsAfterProducerDisconnect) {
229274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
229374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
229474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
229574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
229674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
229774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
229874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
229974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
230074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
230174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
230274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
230374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
230474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
230574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
230674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
230774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
230874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
230974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
231074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
231174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
231274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
231374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(SECOND_TEX_ID, texBinding);
231474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
231574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the secondary context.
231674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
231774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
231874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
231974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mSecondTextureRenderer->drawTexture();
232074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
232174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
232274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
232374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
232474bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
232574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        AttachToContextSucceedsBeforeUpdateTexImage) {
232674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
232774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
232874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
232974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
233074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
233174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
233274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
233374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
233474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
233574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
233674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
233774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
233874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
233974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
234074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
234174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
234274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
234374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(SECOND_TEX_ID, texBinding);
234474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
234574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
234674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
234774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
234874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
234974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the secondary context.
235074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
235174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
235274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
235374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mSecondTextureRenderer->drawTexture();
235474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
235574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
235674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
235774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
235874bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAbandoned) {
235974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
236074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
236174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
236274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
236374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
236474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
236574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
236674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
236774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
236874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
236974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
237074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
237174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach to the secondary context.
237274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->abandon();
237374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
237474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach to the primary context.
237574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(NO_INIT, mST->attachToContext(SECOND_TEX_ID));
237674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
237774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
237874bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAttached) {
237974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
238074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
238174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
238274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
238374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
238474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
238574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
238674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
238774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
238874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach to the primary context.
238974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
239074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
239174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
239274bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
239374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        AttachToContextFailsWhenAttachedBeforeUpdateTexImage) {
239474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
239574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
239674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
239774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
239874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
239974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach to the primary context.
240074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
240174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
240274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
240374bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWithNoDisplay) {
240474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
240574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
240674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
240774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
240874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
240974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
241074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
241174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
241274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
241374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
241474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
241574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
241674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Make there be no current display.
241774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
241874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            EGL_NO_CONTEXT));
241974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
242074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
242174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach with no context current.
242274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
242374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
242474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
242574bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceedsTwice) {
242674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
242774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
242874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
242974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
243074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
243174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
243274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
243374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
243474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
243574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
243674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
243774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
243874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
243974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
244074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
244174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
244274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
244374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the secondary context.
244474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
244574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
244674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the tertiary context.
244774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
244874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mThirdEglContext));
244974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
245074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
245174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
245274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
245374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
245474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(THIRD_TEX_ID, texBinding);
245574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
245674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the tertiary context.
245774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
245874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
245974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
246074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mThirdTextureRenderer->drawTexture();
246174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
246274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
246374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
246474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
246574bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
246674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        AttachToContextSucceedsTwiceBeforeUpdateTexImage) {
246774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<FrameWaiter> fw(new FrameWaiter);
246874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->setFrameAvailableListener(fw);
246974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
247074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
247174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
247274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
247374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
247474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
247574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
247674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
247774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
247874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
247974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
248074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the secondary context.
248174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
248274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
248374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the tertiary context.
248474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
248574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mThirdEglContext));
248674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
248774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
248874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
248974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
249074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
249174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(THIRD_TEX_ID, texBinding);
249274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
249374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the tertiary context.
249474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    fw->waitForFrame();
249574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
249674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
249774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the tertiary context.
249874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
249974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
250074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
250174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mThirdTextureRenderer->drawTexture();
250274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
250374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
2504ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis}
2505ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
25065451d15ee209f29d64beea87583f7058dee69911Jamie Gennis} // namespace android
2507