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>
212adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden#include <gui/GLConsumer.h>
22d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <ui/GraphicBuffer.h>
23d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <utils/String8.h>
245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis#include <utils/threads.h>
25d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
2690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h>
2790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/Surface.h>
2890ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/SurfaceComposerClient.h>
29d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
30d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <EGL/egl.h>
31d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <EGL/eglext.h>
32f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian#include <GLES/gl.h>
33f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian#include <GLES/glext.h>
34d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <GLES2/gl2.h>
35d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <GLES2/gl2ext.h>
36d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
37d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis#include <ui/FramebufferNativeWindow.h>
38f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian#include <utils/UniquePtr.h>
39f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian#include <android/native_window.h>
40d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
41d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisnamespace android {
42d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
43d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisclass GLTest : public ::testing::Test {
44d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisprotected:
45d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
46d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    GLTest():
47d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglDisplay(EGL_NO_DISPLAY),
48d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglSurface(EGL_NO_SURFACE),
49d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mEglContext(EGL_NO_CONTEXT) {
50d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
51d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
52d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void SetUp() {
53fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        const ::testing::TestInfo* const testInfo =
54fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            ::testing::UnitTest::GetInstance()->current_test_info();
55fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
56fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                testInfo->name());
57fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
58d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
59d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
60d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
61d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
62d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint majorVersion;
63d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint minorVersion;
64d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
65d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
66d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglVersionMajor", majorVersion);
67d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglVersionMajor", minorVersion);
68d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
69d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint numConfigs = 0;
701876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
71d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                1, &numConfigs));
72d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
73d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
74d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
75d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (displaySecsEnv != NULL) {
76d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mDisplaySecs = atoi(displaySecsEnv);
77d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (mDisplaySecs < 0) {
78d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                mDisplaySecs = 0;
79d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
80d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
81d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mDisplaySecs = 0;
82d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
83d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
84d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mDisplaySecs > 0) {
85d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mComposerClient = new SurfaceComposerClient;
86d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
87d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
88fc850124b35abd00a31e9bcf57e14e0fa74f4cd7Jamie Gennis            mSurfaceControl = mComposerClient->createSurface(
899d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown                    String8("Test Surface"),
90d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    getSurfaceWidth(), getSurfaceHeight(),
91d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    PIXEL_FORMAT_RGB_888, 0);
92d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
93d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_TRUE(mSurfaceControl != NULL);
94d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_TRUE(mSurfaceControl->isValid());
95d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
96698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            SurfaceComposerClient::openGlobalTransaction();
975dd0c4fd7efcb99bdd346ed01f1a8f1d2baa8ef1Jamie Gennis            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
98d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
99698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian            SurfaceComposerClient::closeGlobalTransaction();
100d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
101d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            sp<ANativeWindow> window = mSurfaceControl->getSurface();
1021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
103d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    window.get(), NULL);
104d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
105d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGLint pbufferAttribs[] = {
106d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_WIDTH, getSurfaceWidth(),
107d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_HEIGHT, getSurfaceHeight(),
108d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                EGL_NONE };
109d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
1101876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
111d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    pbufferAttribs);
112d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
113d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
114d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
115d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
1161876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
117d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                getContextAttribs());
118d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
119d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
120d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
121d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
122d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                mEglContext));
123d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
124d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
125d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EGLint w, h;
126d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
127d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
128d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
129d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
130d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglSurfaceWidth", w);
131d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        RecordProperty("EglSurfaceHeight", h);
132d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
133d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glViewport(0, 0, w, h);
134d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
135d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
136d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
137d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void TearDown() {
1389abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        // Display the result
139d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
140d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglSwapBuffers(mEglDisplay, mEglSurface);
141d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            sleep(mDisplaySecs);
142d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
143d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
144d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mComposerClient != NULL) {
145d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            mComposerClient->dispose();
146d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
147d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglContext != EGL_NO_CONTEXT) {
148d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglDestroyContext(mEglDisplay, mEglContext);
149d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
150d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglSurface != EGL_NO_SURFACE) {
151d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglDestroySurface(mEglDisplay, mEglSurface);
152d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
153d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (mEglDisplay != EGL_NO_DISPLAY) {
154d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
155d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    EGL_NO_CONTEXT);
156d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            eglTerminate(mEglDisplay);
157d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
158d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
159fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
160fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        const ::testing::TestInfo* const testInfo =
161fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis            ::testing::UnitTest::GetInstance()->current_test_info();
162fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis        ALOGV("End test:   %s.%s", testInfo->test_case_name(),
163fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis                testInfo->name());
164d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
165d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
166d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint const* getConfigAttribs() {
167d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        static EGLint sDefaultConfigAttribs[] = {
168d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
169d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
170d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_RED_SIZE, 8,
171d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_GREEN_SIZE, 8,
172d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_BLUE_SIZE, 8,
173d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_ALPHA_SIZE, 8,
174d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_DEPTH_SIZE, 16,
175d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_STENCIL_SIZE, 8,
176d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_NONE };
177d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
178d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        return sDefaultConfigAttribs;
179d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
180d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
181d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint const* getContextAttribs() {
182d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        static EGLint sDefaultContextAttribs[] = {
183d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_CONTEXT_CLIENT_VERSION, 2,
184d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            EGL_NONE };
185d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
186d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        return sDefaultContextAttribs;
187d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
188d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
189d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint getSurfaceWidth() {
190c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis        return 512;
191d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
192d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
193d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual EGLint getSurfaceHeight() {
194c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis        return 512;
195d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
196d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
197d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ::testing::AssertionResult checkPixel(int x, int y, int r,
198824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis            int g, int b, int a, int tolerance=2) {
199d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLubyte pixel[4];
200d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        String8 msg;
201d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
202d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLenum err = glGetError();
203d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (err != GL_NO_ERROR) {
204d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("error reading pixel: %#x", err);
205d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            while ((err = glGetError()) != GL_NO_ERROR) {
206d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += String8::format(", %#x", err);
207d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
208d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionFailure(
209d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    ::testing::Message(msg.string()));
210d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
211824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
212d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("r(%d isn't %d)", pixel[0], r);
213d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
214824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
215d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
216d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
217d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
218d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("g(%d isn't %d)", pixel[1], g);
219d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
220824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
221d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
222d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
223d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
224d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("b(%d isn't %d)", pixel[2], b);
225d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
226824efa74e7ff0a8dd95302daf73c23a056da0d07Jamie Gennis        if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
227d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (!msg.isEmpty()) {
228d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                msg += " ";
229d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
230d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            msg += String8::format("a(%d isn't %d)", pixel[3], a);
231d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
232d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        if (!msg.isEmpty()) {
233d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionFailure(
234d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    ::testing::Message(msg.string()));
235d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        } else {
236d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            return ::testing::AssertionSuccess();
237d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
238d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
239d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
240016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ::testing::AssertionResult assertRectEq(const Rect &r1,
241016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        const Rect &r2, int tolerance=1) {
242016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
243016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        String8 msg;
244016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
245016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        if (abs(r1.left - r2.left) > tolerance) {
246016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            msg += String8::format("left(%d isn't %d)", r1.left, r2.left);
247016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        }
248016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        if (abs(r1.top - r2.top) > tolerance) {
249016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            if (!msg.isEmpty()) {
250016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam                msg += " ";
251016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            }
252016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            msg += String8::format("top(%d isn't %d)", r1.top, r2.top);
253016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        }
254016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        if (abs(r1.right - r2.right) > tolerance) {
255016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            if (!msg.isEmpty()) {
256016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam                msg += " ";
257016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            }
258016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            msg += String8::format("right(%d isn't %d)", r1.right, r2.right);
259016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        }
260016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        if (abs(r1.bottom - r2.bottom) > tolerance) {
261016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            if (!msg.isEmpty()) {
262016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam                msg += " ";
263016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            }
264016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom);
265016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        }
266016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        if (!msg.isEmpty()) {
267016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]",
268016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam                r1.left, r1.top, r1.right, r1.bottom,
269016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam                r2.left, r2.top, r2.right, r2.bottom);
270016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            fprintf(stderr, "assertRectEq: %s\n", msg.string());
271016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            return ::testing::AssertionFailure(
272016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam                    ::testing::Message(msg.string()));
273016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        } else {
274016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam            return ::testing::AssertionSuccess();
275016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        }
276016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    }
277016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
278d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int mDisplaySecs;
279d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceComposerClient> mComposerClient;
280d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<SurfaceControl> mSurfaceControl;
281d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
282d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLDisplay mEglDisplay;
283d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLSurface mEglSurface;
284d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EGLContext mEglContext;
2851876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EGLConfig  mGlConfig;
286d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis};
287d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
28874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic void loadShader(GLenum shaderType, const char* pSource,
28974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLuint* outShader) {
29074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLuint shader = glCreateShader(shaderType);
29174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
29274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    if (shader) {
29374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glShaderSource(shader, 1, &pSource, NULL);
29474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
29574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glCompileShader(shader);
29674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
29774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint compiled = 0;
29874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
29974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
30074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        if (!compiled) {
30174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            GLint infoLen = 0;
30274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
30374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
30474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            if (infoLen) {
30574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                char* buf = (char*) malloc(infoLen);
30674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                if (buf) {
30774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
30874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    printf("Shader compile log:\n%s\n", buf);
30974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    free(buf);
31074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    FAIL();
31174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                }
31274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            } else {
31374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                char* buf = (char*) malloc(0x1000);
31474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                if (buf) {
31574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    glGetShaderInfoLog(shader, 0x1000, NULL, buf);
31674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    printf("Shader compile log:\n%s\n", buf);
31774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    free(buf);
31874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    FAIL();
31974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                }
32074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            }
32174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glDeleteShader(shader);
32274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            shader = 0;
32374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
32474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
32574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(shader != 0);
32674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    *outShader = shader;
32774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
32874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
32974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic void createProgram(const char* pVertexSource,
33074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        const char* pFragmentSource, GLuint* outPgm) {
33174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLuint vertexShader, fragmentShader;
33274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    {
33374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        SCOPED_TRACE("compiling vertex shader");
33474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource,
33574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                &vertexShader));
33674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
33774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    {
33874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        SCOPED_TRACE("compiling fragment shader");
33974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource,
34074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                &fragmentShader));
34174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
34274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
34374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLuint program = glCreateProgram();
34474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
34574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    if (program) {
34674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glAttachShader(program, vertexShader);
34774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
34874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glAttachShader(program, fragmentShader);
34974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
35074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glLinkProgram(program);
35174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint linkStatus = GL_FALSE;
35274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
35374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        if (linkStatus != GL_TRUE) {
35474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            GLint bufLength = 0;
35574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
35674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            if (bufLength) {
35774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                char* buf = (char*) malloc(bufLength);
35874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                if (buf) {
35974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    glGetProgramInfoLog(program, bufLength, NULL, buf);
36074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    printf("Program link log:\n%s\n", buf);
36174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    free(buf);
36274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    FAIL();
36374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                }
36474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            }
36574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glDeleteProgram(program);
36674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            program = 0;
36774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
36874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
36974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glDeleteShader(vertexShader);
37074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glDeleteShader(fragmentShader);
37174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(program != 0);
37274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    *outPgm = program;
37374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
37474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
37574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic int abs(int value) {
37674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    return value > 0 ? value : -value;
37774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
37874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
37974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
380d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// XXX: Code above this point should live elsewhere
381d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
382f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopianclass MultiTextureConsumerTest : public GLTest {
383f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopianprotected:
384f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    enum { TEX_ID = 123 };
385f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
386f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    virtual void SetUp() {
387f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        GLTest::SetUp();
3888f938a53385a3c6d1c6aa24b3f38437bb2cc47aeMathias Agopian        sp<BufferQueue> bq = new BufferQueue();
3898f938a53385a3c6d1c6aa24b3f38437bb2cc47aeMathias Agopian        mGlConsumer = new GLConsumer(bq, TEX_ID);
390db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian        mSurface = new Surface(bq);
391f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        mANW = mSurface.get();
392f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
393f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    }
394f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    virtual void TearDown() {
395f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        GLTest::TearDown();
396f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    }
397f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    virtual EGLint const* getContextAttribs() {
398f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        return NULL;
399f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    }
400f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    virtual EGLint const* getConfigAttribs() {
401f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        static EGLint sDefaultConfigAttribs[] = {
402f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
403f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian            EGL_RED_SIZE, 8,
404f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian            EGL_GREEN_SIZE, 8,
405f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian            EGL_BLUE_SIZE, 8,
406f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian            EGL_ALPHA_SIZE, 8,
407f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian            EGL_NONE };
408f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
409f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        return sDefaultConfigAttribs;
410f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    }
411f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    sp<GLConsumer> mGlConsumer;
412f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    sp<Surface> mSurface;
413f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    ANativeWindow* mANW;
414f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian};
415f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
416f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
417f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias AgopianTEST_F(MultiTextureConsumerTest, EGLImageTargetWorks) {
418f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    ANativeWindow_Buffer buffer;
419f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
420f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    ASSERT_EQ(native_window_set_usage(mANW, GRALLOC_USAGE_SW_WRITE_OFTEN), NO_ERROR);
421f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    ASSERT_EQ(native_window_set_buffers_format(mANW, HAL_PIXEL_FORMAT_RGBA_8888), NO_ERROR);
422f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
423f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glShadeModel(GL_FLAT);
424f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glDisable(GL_DITHER);
425f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glDisable(GL_CULL_FACE);
426f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glViewport(0, 0, getSurfaceWidth(), getSurfaceHeight());
427f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glOrthof(0, getSurfaceWidth(), 0, getSurfaceHeight(), 0, 1);
428f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glEnableClientState(GL_VERTEX_ARRAY);
429f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glColor4f(1, 1, 1, 1);
430f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
431f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
432f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
433f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
434f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
435f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
436f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
437f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    uint32_t texel = 0x80808080;
438f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glBindTexture(GL_TEXTURE_2D, TEX_ID+1);
439f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texel);
440f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
441f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
442f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
443f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
444f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
445f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glActiveTexture(GL_TEXTURE1);
446f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glBindTexture(GL_TEXTURE_2D, TEX_ID+1);
447f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glEnable(GL_TEXTURE_2D);
448f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
449f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
450f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glActiveTexture(GL_TEXTURE0);
451f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
452f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glEnable(GL_TEXTURE_EXTERNAL_OES);
453f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
454f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
455f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
456f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    for (int i=0 ; i<8 ; i++) {
457f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        mSurface->lock(&buffer, NULL);
458f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        memset(buffer.bits, (i&7) * 0x20, buffer.stride * buffer.height * 4);
459f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        mSurface->unlockAndPost();
460f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
461f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        mGlConsumer->updateTexImage();
462f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
463f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        GLfloat vertices[][2] = { {i*16.0f, 0}, {(i+1)*16.0f, 0}, {(i+1)*16.0f, 16.0f}, {i*16.0f, 16.0f} };
464f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        glVertexPointer(2, GL_FLOAT, 0, vertices);
465f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
466f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
467ea2d942ddaea11ca5f136e27e0ab8bcd72bb0644Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
468f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    }
469f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
470f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    for (int i=0 ; i<8 ; i++) {
471ea2d942ddaea11ca5f136e27e0ab8bcd72bb0644Jamie Gennis        EXPECT_TRUE(checkPixel(i*16 + 8,  8, i*16, i*16, i*16, i*16, 0));
472f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian    }
473f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian}
474f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
475f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
476f31510a2ac0807cf3d4224a73fc3f8f691f42f5aMathias Agopian
477d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisclass SurfaceTextureGLTest : public GLTest {
478d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisprotected:
47979e3125d56cca5aba88097b5ccd4f1e128bc8141Jamie Gennis    enum { TEX_ID = 123 };
480d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
481d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    virtual void SetUp() {
482d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        GLTest::SetUp();
4838f938a53385a3c6d1c6aa24b3f38437bb2cc47aeMathias Agopian        sp<BufferQueue> bq = new BufferQueue();
484db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian        mBQ = bq;
4858f938a53385a3c6d1c6aa24b3f38437bb2cc47aeMathias Agopian        mST = new GLConsumer(bq, TEX_ID);
486db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian        mSTC = new Surface(bq);
487d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        mANW = mSTC;
48874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mTextureRenderer = new TextureRenderer(TEX_ID, mST);
48974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp());
490efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis        mFW = new FrameWaiter;
491efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis        mST->setFrameAvailableListener(mFW);
492d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
493d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
4942640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis    virtual void TearDown() {
4952640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        mANW.clear();
4962640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        mSTC.clear();
4972640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        mST.clear();
4982640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        GLTest::TearDown();
4992640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis    }
5002640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis
501d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    void drawTexture() {
50274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mTextureRenderer->drawTexture();
50374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    }
504d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
50574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    class TextureRenderer: public RefBase {
50674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    public:
5072adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        TextureRenderer(GLuint texName, const sp<GLConsumer>& st):
50874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mTexName(texName),
50974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mST(st) {
51074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
511d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
51274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        void SetUp() {
51374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            const char vsrc[] =
51474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "attribute vec4 vPosition;\n"
51574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "varying vec2 texCoords;\n"
51674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "uniform mat4 texMatrix;\n"
51774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "void main() {\n"
51874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
51974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
52074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "  gl_Position = vPosition;\n"
52174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "}\n";
52274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
52374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            const char fsrc[] =
52474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "#extension GL_OES_EGL_image_external : require\n"
52574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "precision mediump float;\n"
52674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "uniform samplerExternalOES texSampler;\n"
52774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "varying vec2 texCoords;\n"
52874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "void main() {\n"
52974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "  gl_FragColor = texture2D(texSampler, texCoords);\n"
53074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                "}\n";
53174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
53274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            {
53374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                SCOPED_TRACE("creating shader program");
53474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                ASSERT_NO_FATAL_FAILURE(createProgram(vsrc, fsrc, &mPgm));
53574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            }
5361876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
53774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
53874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
53974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_NE(-1, mPositionHandle);
54074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
54174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
54274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_NE(-1, mTexSamplerHandle);
54374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
54474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
54574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_NE(-1, mTexMatrixHandle);
54674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
547d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
5482adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        // drawTexture draws the GLConsumer over the entire GL viewport.
54974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        void drawTexture() {
550a96b6bdea3d5ece7b1f3bcae40e9fe632ebc8f22Jamie Gennis            static const GLfloat triangleVertices[] = {
55174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                -1.0f, 1.0f,
55274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                -1.0f, -1.0f,
55374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                1.0f, -1.0f,
55474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                1.0f, 1.0f,
55574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            };
55674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
55774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
55874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    triangleVertices);
55974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
56074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glEnableVertexAttribArray(mPositionHandle);
56174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
56274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
56374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glUseProgram(mPgm);
56474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glUniform1i(mTexSamplerHandle, 0);
56574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
56674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName);
56774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
56874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
56974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
57074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            // they're setting the defautls for that target, but when hacking
57174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            // things to use GL_TEXTURE_2D they are needed to achieve the same
57274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            // behavior.
57374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
57474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    GL_LINEAR);
57574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
57674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
57774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    GL_LINEAR);
57874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
57974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
58074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    GL_CLAMP_TO_EDGE);
58174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
58274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
58374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                    GL_CLAMP_TO_EDGE);
58474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
58574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
58674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            GLfloat texMatrix[16];
58774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mST->getTransformMatrix(texMatrix);
58874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
58974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
59074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
59174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
59274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
59374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
59474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLuint mTexName;
5952adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        sp<GLConsumer> mST;
59674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLuint mPgm;
59774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint mPositionHandle;
59874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint mTexSamplerHandle;
59974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        GLint mTexMatrixHandle;
60074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    };
601d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
6022adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    class FrameWaiter : public GLConsumer::FrameAvailableListener {
603dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    public:
604dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        FrameWaiter():
605dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                mPendingFrames(0) {
606dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
607dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
608dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        void waitForFrame() {
609dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            Mutex::Autolock lock(mMutex);
610dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            while (mPendingFrames == 0) {
611dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                mCondition.wait(mMutex);
612dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            }
613dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            mPendingFrames--;
614dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
615dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
616dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        virtual void onFrameAvailable() {
617dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            Mutex::Autolock lock(mMutex);
618dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            mPendingFrames++;
619dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            mCondition.signal();
620dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
621dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
622dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        int mPendingFrames;
623dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        Mutex mMutex;
624dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        Condition mCondition;
625dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    };
626dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
6272adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    // Note that GLConsumer will lose the notifications
6289abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // onBuffersReleased and onFrameAvailable as there is currently
6299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // no way to forward the events.  This DisconnectWaiter will not let the
6309abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // disconnect finish until finishDisconnect() is called.  It will
6319abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // also block until a disconnect is called
632a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0bMathias Agopian    class DisconnectWaiter : public BnConsumerListener {
6339abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    public:
6349abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        DisconnectWaiter () :
6359abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mWaitForDisconnect(false),
6369abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mPendingFrames(0) {
6379abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
6389abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
6399abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        void waitForFrame() {
6409abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            Mutex::Autolock lock(mMutex);
6419abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            while (mPendingFrames == 0) {
6429abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                mFrameCondition.wait(mMutex);
6439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            }
6449abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mPendingFrames--;
6459abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
6469abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
6479abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        virtual void onFrameAvailable() {
6489abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            Mutex::Autolock lock(mMutex);
6499abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mPendingFrames++;
6509abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mFrameCondition.signal();
6519abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
6529abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
6539abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        virtual void onBuffersReleased() {
6549abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            Mutex::Autolock lock(mMutex);
6559abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            while (!mWaitForDisconnect) {
6569abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                mDisconnectCondition.wait(mMutex);
6579abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            }
6589abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
6599abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
6609abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        void finishDisconnect() {
6619abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            Mutex::Autolock lock(mMutex);
6629abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mWaitForDisconnect = true;
6639abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            mDisconnectCondition.signal();
6649abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
6659abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
6669abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    private:
6679abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        Mutex mMutex;
6689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
6699abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        bool mWaitForDisconnect;
6709abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        Condition mDisconnectCondition;
6719abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
6729abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        int mPendingFrames;
6739abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        Condition mFrameCondition;
6749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    };
6759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
676db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    sp<BufferQueue> mBQ;
6772adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    sp<GLConsumer> mST;
678e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian    sp<Surface> mSTC;
679d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<ANativeWindow> mANW;
68074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<TextureRenderer> mTextureRenderer;
681efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    sp<FrameWaiter> mFW;
682d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis};
683d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
684d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// Fill a YV12 buffer with a multi-colored checkerboard pattern
685d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisvoid fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
686d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int blockWidth = w > 16 ? w / 16 : 1;
687d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int blockHeight = h > 16 ? h / 16 : 1;
688d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int yuvTexOffsetY = 0;
689d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideY = stride;
690d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetV = yuvTexStrideY * h;
691d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
692d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
693d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideU = yuvTexStrideV;
694d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int x = 0; x < w; x++) {
695d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        for (int y = 0; y < h; y++) {
696d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            int parityX = (x / blockWidth) & 1;
697d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            int parityY = (y / blockHeight) & 1;
698d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
699d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
700d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (x < w / 2 && y < h / 2) {
701d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
702d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                if (x * 2 < w / 2 && y * 2 < h / 2) {
703d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
704d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
705d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
706d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
707d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        intensity;
708d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                }
709d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
710d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
711d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
712d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
713d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
714d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// Fill a YV12 buffer with red outside a given rectangle and green inside it.
715d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisvoid fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
716d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const android_native_rect_t& rect) {
717d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    const int yuvTexOffsetY = 0;
718d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideY = stride;
719d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetV = yuvTexStrideY * h;
720d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
721d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
722d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    int yuvTexStrideU = yuvTexStrideV;
723d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int x = 0; x < w; x++) {
724d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        for (int y = 0; y < h; y++) {
725d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            bool inside = rect.left <= x && x < rect.right &&
726d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                    rect.top <= y && y < rect.bottom;
727d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
728d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            if (x < w / 2 && y < h / 2) {
729d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                bool inside = rect.left <= 2*x && 2*x < rect.right &&
730d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        rect.top <= 2*y && 2*y < rect.bottom;
731d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
732d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
733d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis                        inside ? 16 : 255;
734d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            }
735d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        }
736d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
737d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
738d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
7391876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennisvoid fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
7401876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const size_t PIXEL_SIZE = 4;
7411876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    for (int x = 0; x < w; x++) {
7421876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        for (int y = 0; y < h; y++) {
7431876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            off_t offset = (y * stride + x) * PIXEL_SIZE;
7441876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            for (int c = 0; c < 4; c++) {
7451876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                int parityX = (x / (1 << (c+2))) & 1;
7461876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                int parityY = (y / (1 << (c+2))) & 1;
7471876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis                buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
7481876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            }
7491876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        }
7501876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    }
7511876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
7521876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
753fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisvoid fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
754fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        uint8_t g, uint8_t b, uint8_t a) {
755fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    const size_t PIXEL_SIZE = 4;
756fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    for (int y = 0; y < h; y++) {
757fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        for (int x = 0; x < h; x++) {
758fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            off_t offset = (y * stride + x) * PIXEL_SIZE;
759fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            buf[offset + 0] = r;
760fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            buf[offset + 1] = g;
761fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            buf[offset + 2] = b;
762fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            buf[offset + 3] = a;
763fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        }
764fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    }
765fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis}
766fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
767ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// Produce a single RGBA8 frame by filling a buffer with a checkerboard pattern
768ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// using the CPU.  This assumes that the ANativeWindow is already configured to
769ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// allow this to be done (e.g. the format is set to RGBA8).
770ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis//
771ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// Calls to this function should be wrapped in an ASSERT_NO_FATAL_FAILURE().
772ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisvoid produceOneRGBA8Frame(const sp<ANativeWindow>& anw) {
773ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    android_native_buffer_t* anb;
774d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(),
775d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            &anb));
776ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_TRUE(anb != NULL);
777ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
778ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
779ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
780ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    uint8_t* img = NULL;
781ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
782ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis            (void**)(&img)));
783ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    fillRGBA8Buffer(img, buf->getWidth(), buf->getHeight(), buf->getStride());
784ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(NO_ERROR, buf->unlock());
785d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf->getNativeBuffer(),
786d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            -1));
787ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis}
788ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
789d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
7901876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
7911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
792d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
793d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
7941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
795d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
796d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
797d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
798697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    ANativeWindowBuffer* anb;
799d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
800d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            &anb));
801d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_TRUE(anb != NULL);
802d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
803d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
804d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
805d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    // Fill the buffer with the a checkerboard pattern
806d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    uint8_t* img = NULL;
807d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
8081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
809d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->unlock();
810d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
811d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            -1));
812d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
813d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
814d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
815d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
816d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
817d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
818c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
819d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    drawTexture();
820d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
821e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255, 3));
822e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255, 3));
823e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel(63, 65,   0, 133,   0, 255, 3));
824e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255, 3));
825e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis
826e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255, 3));
827e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255, 3));
828e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel(52, 51,  98, 255,  73, 255, 3));
829e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255, 3));
830e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel(31,  9, 107,  24,  87, 255, 3));
831e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255, 3));
832e6a0f5028b3ef81916e7fd58a64f76861bfa78e0Jamie Gennis    EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255, 3));
833d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
834d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
835d05bb2ed4c99894965134994cf23c9e47274f56eJamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
8361876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
8371876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
838d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
839d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
8401876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
841d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
842d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
843d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
844697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev    ANativeWindowBuffer* anb;
845d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
846d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            &anb));
847d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_TRUE(anb != NULL);
848d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
849d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
850d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
851d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    // Fill the buffer with the a checkerboard pattern
852d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    uint8_t* img = NULL;
853d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
8541876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
855d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    buf->unlock();
856d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
857d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            -1));
858d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
859d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
860d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
861d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
862d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
863d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
864c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
865d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    drawTexture();
866d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
867d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0,   0, 133,   0, 255));
868d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 255, 127, 255, 255));
869d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
870d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
871d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
872d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255));
873d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255));
874d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255));
875d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
876d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255));
877d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255));
878d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis    EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
879d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
880d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
881d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
8821876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
8831876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
884d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
885d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
8861876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
887d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
888d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
889d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
890d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    android_native_rect_t crops[] = {
891d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {4, 6, 22, 36},
892d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {0, 6, 22, 36},
893d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        {4, 0, 22, 36},
8941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        {4, 6, texWidth, 36},
8951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        {4, 6, 22, texHeight},
896d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    };
897d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
898d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    for (int i = 0; i < 5; i++) {
899d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        const android_native_rect_t& crop(crops[i]);
9006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
9016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                crop.left, crop.top, crop.right, crop.bottom).string());
902d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
903d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
904d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
905697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev        ANativeWindowBuffer* anb;
906d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
907d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                &anb));
908d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        ASSERT_TRUE(anb != NULL);
909d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
910d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
911d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
912d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        uint8_t* img = NULL;
913d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
9141876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis        fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
915d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        buf->unlock();
9166f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
917d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                buf->getNativeBuffer(), -1));
918d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
919d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
920d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
921d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glClearColor(0.2, 0.2, 0.2, 0.2);
922d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
923d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
924c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis        glViewport(0, 0, 64, 64);
925d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        drawTexture();
926d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
927d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
928d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
929d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
930d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
931d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
932d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
933d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
934d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
935d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
936d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
937d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
938d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis        EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
939d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis    }
940d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
941d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis
942dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis// This test is intended to catch synchronization bugs between the CPU-written
943dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis// and GPU-read buffers.
944dfcff4b4ef8b602ba485848b394b16d14847821eJamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
945dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    enum { texWidth = 16 };
946dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    enum { texHeight = 16 };
947dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    enum { numFrames = 1024 };
948dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
94931a353da225af5329735451c761b430d82dfda1bJamie Gennis    ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
950dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
951dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
952dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
953dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            GRALLOC_USAGE_SW_WRITE_OFTEN));
954dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
955dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    struct TestPixel {
956dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        int x;
957dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        int y;
958dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    };
959dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    const TestPixel testPixels[] = {
960dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        {  4, 11 },
961dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        { 12, 14 },
962dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        {  7,  2 },
963dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    };
964dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
965dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
966dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    class ProducerThread : public Thread {
967dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    public:
9686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ProducerThread(const sp<ANativeWindow>& anw,
9696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                const TestPixel* testPixels):
970dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                mANW(anw),
971dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                mTestPixels(testPixels) {
972dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
973dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
974dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        virtual ~ProducerThread() {
975dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
976dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
977dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        virtual bool threadLoop() {
978dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            for (int i = 0; i < numFrames; i++) {
979dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                ANativeWindowBuffer* anb;
980d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                if (native_window_dequeue_buffer_and_wait(mANW.get(),
981d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                        &anb) != NO_ERROR) {
982dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    return false;
983dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
984dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                if (anb == NULL) {
985dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    return false;
986dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
987dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
988dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
989dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
990dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                const int yuvTexOffsetY = 0;
991dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int stride = buf->getStride();
992dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexStrideY = stride;
993dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexOffsetV = yuvTexStrideY * texHeight;
994dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
995dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
996dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                int yuvTexStrideU = yuvTexStrideV;
997dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
998dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                uint8_t* img = NULL;
999dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
1000dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1001dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // Gray out all the test pixels first, so we're more likely to
1002dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // see a failure if GL is still texturing from the buffer we
1003dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // just dequeued.
1004dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                for (int j = 0; j < numTestPixels; j++) {
1005dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    int x = mTestPixels[j].x;
1006dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    int y = mTestPixels[j].y;
1007dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    uint8_t value = 128;
1008dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    img[y*stride + x] = value;
1009dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
1010dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1011dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // Fill the buffer with gray.
1012dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                for (int y = 0; y < texHeight; y++) {
1013dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    for (int x = 0; x < texWidth; x++) {
1014dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
1015dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
1016dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
1017dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    }
1018dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
1019dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1020dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // Set the test pixels to either white or black.
1021dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                for (int j = 0; j < numTestPixels; j++) {
1022dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    int x = mTestPixels[j].x;
1023dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    int y = mTestPixels[j].y;
1024dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    uint8_t value = 0;
1025dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    if (j == (i % numTestPixels)) {
1026dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        value = 255;
1027dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    }
1028dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    img[y*stride + x] = value;
1029dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
1030dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1031dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                buf->unlock();
1032d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), -1)
1033dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                        != NO_ERROR) {
1034dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                    return false;
1035dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                }
1036dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            }
1037dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            return false;
1038dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
1039dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1040dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        sp<ANativeWindow> mANW;
1041dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        const TestPixel* mTestPixels;
1042dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    };
1043dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1044dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    sp<Thread> pt(new ProducerThread(mANW, testPixels));
1045dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    pt->run();
1046dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1047dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    glViewport(0, 0, texWidth, texHeight);
1048dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1049dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
1050dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1051dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1052dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    // We wait for the first two frames up front so that the producer will be
1053dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    // likely to dequeue the buffer that's currently being textured from.
1054efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
1055efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
1056dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1057dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    for (int i = 0; i < numFrames; i++) {
1058dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        SCOPED_TRACE(String8::format("frame %d", i).string());
1059dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1060dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        // We must wait for each frame to come in because if we ever do an
1061dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        // updateTexImage call that doesn't consume a newly available buffer
1062dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        // then the producer and consumer will get out of sync, which will cause
1063dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        // a deadlock.
1064dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        if (i > 1) {
1065efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis            mFW->waitForFrame();
1066dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
1067d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
1068dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        drawTexture();
1069dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1070dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        for (int j = 0; j < numTestPixels; j++) {
1071dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            int x = testPixels[j].x;
1072dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            int y = testPixels[j].y;
1073dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            uint8_t value = 0;
1074dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            if (j == (i % numTestPixels)) {
1075dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // We must y-invert the texture coords
1076dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
1077dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            } else {
1078dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                // We must y-invert the texture coords
1079dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis                EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
1080dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis            }
1081dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis        }
1082dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    }
1083dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
1084dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis    pt->requestExitAndWait();
1085dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis}
1086dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis
10871f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
10881876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
10891876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 66;
10901876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
10911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
10921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
10931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
10941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
10951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1096ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
10971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1098d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
10991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11001876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
11011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
11021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1103c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
11041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
11051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
11071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
1108c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
1109c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel( 0, 65,  35,  35,  35,  35));
11101876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
11121f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(23, 65, 231,  35, 231,  35));
1113c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    EXPECT_TRUE(checkPixel(19, 40,  35, 231,  35,  35));
11141876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
11151876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
11161f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(37, 34,  35, 231, 231, 231));
11171876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
11181f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(37, 47, 231,  35, 231, 231));
11191f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(25, 38,  35,  35,  35,  35));
11201f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(49,  6,  35, 231,  35,  35));
11211876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
11221f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
11231f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(10,  6,  35,  35, 231, 231));
11241876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
11251f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis    EXPECT_TRUE(checkPixel(55, 28,  35,  35, 231,  35));
11261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
11271876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
11281876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11291f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
11301876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
11311876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
11321876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11331876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
11341876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
11351876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
11361876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
11371876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1138ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
11391876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1140d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
11411876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11421876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
11431876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
11441876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1145c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
11461876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
11471876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11481876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
11491876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
11501876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
11511876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
11521876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11531876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
11541876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
11551876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
11561876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
11571876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
11581876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
11591876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
11601876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
11611876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
11621876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
11631876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
11641876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
11651876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
11661876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
11671876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
11681876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
11691876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
11701876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
11712adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden// Tests if GLConsumer and BufferQueue are robust enough
11729abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// to handle a special case where updateTexImage is called
11739abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// in the middle of disconnect.  This ordering is enforced
11749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// by blocking in the disconnect callback.
11759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel LamTEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
11769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    class ProducerThread : public Thread {
11789abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    public:
11799abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        ProducerThread(const sp<ANativeWindow>& anw):
11809abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                mANW(anw) {
11819abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
11829abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11839abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        virtual ~ProducerThread() {
11849abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
11859abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11869abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        virtual bool threadLoop() {
11879abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            ANativeWindowBuffer* anb;
11889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL);
11909abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
11919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            for (int numFrames =0 ; numFrames < 2; numFrames ++) {
11929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
1193d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                if (native_window_dequeue_buffer_and_wait(mANW.get(),
1194d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                        &anb) != NO_ERROR) {
11959abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                    return false;
11969abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                }
11979abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                if (anb == NULL) {
11989abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                    return false;
11999abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                }
1200d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                if (mANW->queueBuffer(mANW.get(), anb, -1)
12019abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                        != NO_ERROR) {
12029abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                    return false;
12039abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam                }
12049abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            }
12059abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12069abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL);
12079abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12089abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam            return false;
12099abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        }
12109abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12119abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    private:
12129abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam        sp<ANativeWindow> mANW;
12139abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    };
12149abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12159abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    sp<DisconnectWaiter> dw(new DisconnectWaiter());
1216db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian    mBQ->consumerConnect(dw, false);
12179abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12189abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12199abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    sp<Thread> pt(new ProducerThread(mANW));
12209abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    pt->run();
12219abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12222adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    // eat a frame so GLConsumer will own an at least one slot
12239abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    dw->waitForFrame();
12249abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
12259abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12269abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    dw->waitForFrame();
12272adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    // Could fail here as GLConsumer thinks it still owns the slot
12289abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // but bufferQueue has released all slots
12299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
12309abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12319abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    dw->finishDisconnect();
12329abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam}
12339abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12349abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12352adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden// This test ensures that the GLConsumer clears the mCurrentTexture
12369abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// when it is disconnected and reconnected.  Otherwise it will
12379abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// attempt to release a buffer that it does not owned
12389abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel LamTEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
1239efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
1240efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis            NATIVE_WINDOW_API_EGL));
12419abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12429abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    ANativeWindowBuffer *anb;
12439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
1244d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
1245d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
12469abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
1247d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
1248d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
12499abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12509abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
12519abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
12529abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
1253efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
1254efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis            NATIVE_WINDOW_API_EGL));
1255efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
1256efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis            NATIVE_WINDOW_API_EGL));
12579abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
1258d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
1259d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
12609abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
12619abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    // Will fail here if mCurrentTexture is not cleared properly
1262efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
12639abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam    EXPECT_EQ(OK,mST->updateTexImage());
1264efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis
1265efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
1266efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis            NATIVE_WINDOW_API_EGL));
12679abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam}
12689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam
1269016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel LamTEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
1270016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
1271016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
1272016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1273016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // The producer image size
1274016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
1275016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1276016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // The consumer image size (16 x 9) ratio
1277016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    mST->setDefaultBufferSize(1280, 720);
1278016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1279efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
1280efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis            NATIVE_WINDOW_API_CPU));
1281016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1282016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ANativeWindowBuffer *anb;
1283016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1284016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    android_native_rect_t odd = {23, 78, 123, 477};
1285016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &odd));
1286d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
1287d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
1288efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
1289d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    EXPECT_EQ(OK, mST->updateTexImage());
1290016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    Rect r = mST->getCurrentCrop();
1291016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    assertRectEq(Rect(23, 78, 123, 477), r);
1292016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1293efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
1294efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis            NATIVE_WINDOW_API_CPU));
1295016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam}
1296016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1297016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam// This test ensures the scaling mode does the right thing
1298016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam// ie NATIVE_WINDOW_SCALING_MODE_CROP should crop
1299016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam// the image such that it has the same aspect ratio as the
1300016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam// default buffer size
1301016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel LamTEST_F(SurfaceTextureGLTest, CroppedScalingMode) {
1302016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
1303016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam        NATIVE_WINDOW_SCALING_MODE_SCALE_CROP));
1304016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1305016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // The producer image size
1306016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
1307016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1308016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // The consumer image size (16 x 9) ratio
1309016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    mST->setDefaultBufferSize(1280, 720);
1310016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1311016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU);
1312016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1313016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ANativeWindowBuffer *anb;
1314016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1315016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // The crop is in the shape of (320, 180) === 16 x 9
1316016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    android_native_rect_t standard = {10, 20, 330, 200};
1317016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &standard));
1318d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
1319d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
1320efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
1321d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    EXPECT_EQ(OK, mST->updateTexImage());
1322016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    Rect r = mST->getCurrentCrop();
1323016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // crop should be the same as crop (same aspect ratio)
1324016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    assertRectEq(Rect(10, 20, 330, 200), r);
1325016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1326016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // make this wider then desired aspect 239 x 100 (2.39:1)
1327016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    android_native_rect_t wide = {20, 30, 259, 130};
1328016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &wide));
1329d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
1330d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
1331efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
1332d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    EXPECT_EQ(OK, mST->updateTexImage());
1333016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    r = mST->getCurrentCrop();
1334016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // crop should be the same height, but have cropped left and right borders
1335016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // offset is 30.6 px L+, R-
1336016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    assertRectEq(Rect(51, 30, 228, 130), r);
1337016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1338016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // This image is taller then desired aspect 400 x 300 (4:3)
1339016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    android_native_rect_t narrow = {0, 0, 400, 300};
1340016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &narrow));
1341d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
1342d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
1343efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
1344d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    EXPECT_EQ(OK, mST->updateTexImage());
1345016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    r = mST->getCurrentCrop();
1346016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // crop should be the same width, but have cropped top and bottom borders
1347016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    // offset is 37.5 px
1348016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    assertRectEq(Rect(0, 37, 400, 262), r);
1349016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
1350016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
1351016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam}
1352016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam
13536f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
13546f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    class ProducerThread : public Thread {
13556f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    public:
13566f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ProducerThread(const sp<ANativeWindow>& anw):
13576f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mANW(anw),
13586f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mDequeueError(NO_ERROR) {
13596f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
13606f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
13616f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        virtual ~ProducerThread() {
13626f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
13636f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
13646f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        virtual bool threadLoop() {
13656f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            Mutex::Autolock lock(mMutex);
13666f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            ANativeWindowBuffer* anb;
13676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
13686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            // Frame 1
1369d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            if (native_window_dequeue_buffer_and_wait(mANW.get(),
1370d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                    &anb) != NO_ERROR) {
13716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
13726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
13736f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            if (anb == NULL) {
13746f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
13756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
1376d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            if (mANW->queueBuffer(mANW.get(), anb, -1)
13776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                    != NO_ERROR) {
13786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
13796f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
13806f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
13816f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            // Frame 2
1382d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            if (native_window_dequeue_buffer_and_wait(mANW.get(),
1383d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                    &anb) != NO_ERROR) {
13846f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
13856f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
13866f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            if (anb == NULL) {
13876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
13886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
1389d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            if (mANW->queueBuffer(mANW.get(), anb, -1)
13906f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                    != NO_ERROR) {
13916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                return false;
13926f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            }
13936f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
13946f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            // Frame 3 - error expected
1395d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            mDequeueError = native_window_dequeue_buffer_and_wait(mANW.get(),
1396d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                &anb);
13976f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            return false;
13986f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
13996f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        status_t getDequeueError() {
14016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            Mutex::Autolock lock(mMutex);
14026f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            return mDequeueError;
14036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
14046f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14056f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    private:
14066f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        sp<ANativeWindow> mANW;
14076f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        status_t mDequeueError;
14086f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        Mutex mMutex;
14096f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    };
14106f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
141131a353da225af5329735451c761b430d82dfda1bJamie Gennis    ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
14126f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14136f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    sp<Thread> pt(new ProducerThread(mANW));
14146f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    pt->run();
14156f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
1416efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
1417efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
14186f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14196f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
14206f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // block waiting for a buffer to become available.
14216f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    usleep(100000);
14226f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14236f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->abandon();
14246f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14256f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    pt->requestExitAndWait();
14266f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_EQ(NO_INIT,
14276f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
14286f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis}
14296f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14306f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
14316f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    int texHeight = 16;
14326f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ANativeWindowBuffer* anb;
14336f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14346f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    GLint maxTextureSize;
14356f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
14366f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14376f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // make sure it works with small textures
14386f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->setDefaultBufferSize(16, texHeight);
1439d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
1440d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            &anb));
14416f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(16, anb->width);
14426f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(texHeight, anb->height);
1443d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
14446f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
14456f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14466f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // make sure it works with GL_MAX_TEXTURE_SIZE
14476f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->setDefaultBufferSize(maxTextureSize, texHeight);
1448d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
1449d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            &anb));
14506f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(maxTextureSize, anb->width);
14516f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(texHeight, anb->height);
1452d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
14536f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
14546f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14556f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // make sure it fails with GL_MAX_TEXTURE_SIZE+1
14566f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
1457d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
1458d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            &anb));
14596f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(maxTextureSize+1, anb->width);
14606f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(texHeight, anb->height);
1461d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
14626f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_NE(NO_ERROR, mST->updateTexImage());
14636f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis}
14646f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14656f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis/*
14666f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * This test fixture is for testing GL -> GL texture streaming.  It creates an
14676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * EGLSurface and an EGLContext for the image producer to use.
14686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis */
14696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisclass SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
14706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisprotected:
14716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    SurfaceTextureGLToGLTest():
14726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            mProducerEglSurface(EGL_NO_SURFACE),
14736f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            mProducerEglContext(EGL_NO_CONTEXT) {
14746f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
14756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14766f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    virtual void SetUp() {
14776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SurfaceTextureGLTest::SetUp();
14786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
1479ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
14806f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mANW.get(), NULL);
14816f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
14826f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
14836f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
1484ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        mProducerEglContext = eglCreateContext(mEglDisplay, mGlConfig,
14856f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                EGL_NO_CONTEXT, getContextAttribs());
14866f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
14876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
14886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
14896f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
14906f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    virtual void TearDown() {
14916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        if (mProducerEglContext != EGL_NO_CONTEXT) {
14926f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            eglDestroyContext(mEglDisplay, mProducerEglContext);
14936f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
14946f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        if (mProducerEglSurface != EGL_NO_SURFACE) {
14956f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            eglDestroySurface(mEglDisplay, mProducerEglSurface);
14966f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        }
14976f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SurfaceTextureGLTest::TearDown();
14986f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
14996f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
15006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EGLSurface mProducerEglSurface;
15016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EGLContext mProducerEglContext;
15026f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis};
15036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis
150471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFaddenTEST_F(SurfaceTextureGLToGLTest, TransformHintGetsRespected) {
150571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    const uint32_t texWidth = 32;
150671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    const uint32_t texHeight = 64;
150771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden
150871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    mST->setDefaultBufferSize(texWidth, texHeight);
150971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
151071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden
151171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // This test requires 3 buffers to avoid deadlock because we're
151271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // both producer and consumer, and only using one thread.
151371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    mST->setDefaultMaxBufferCount(3);
151471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden
151571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // Do the producer side of things
151671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
151771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden            mProducerEglSurface, mProducerEglContext));
151871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    ASSERT_EQ(EGL_SUCCESS, eglGetError());
151971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden
152071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // Start a buffer with our chosen size and transform hint moving
152171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // through the system.
152271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    glClear(GL_COLOR_BUFFER_BIT);  // give the driver something to do
152371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
152471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    mST->updateTexImage();  // consume it
152571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // Swap again.
152671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    glClear(GL_COLOR_BUFFER_BIT);
152771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
152871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    mST->updateTexImage();
152971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden
153071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // The current buffer should either show the effects of the transform
153171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // hint (in the form of an inverse transform), or show that the
153271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // transform hint has been ignored.
153371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    sp<GraphicBuffer> buf = mST->getCurrentBuffer();
153471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    if (mST->getCurrentTransform() == NATIVE_WINDOW_TRANSFORM_ROT_270) {
153571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden        ASSERT_EQ(texWidth, buf->getHeight());
153671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden        ASSERT_EQ(texHeight, buf->getWidth());
153771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    } else {
153871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden        ASSERT_EQ(texWidth, buf->getWidth());
153971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden        ASSERT_EQ(texHeight, buf->getHeight());
154071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    }
154171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden
154271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    // Reset the transform hint and confirm that it takes.
154371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    mST->setTransformHint(0);
154471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    glClear(GL_COLOR_BUFFER_BIT);
154571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
154671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    mST->updateTexImage();
154771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    glClear(GL_COLOR_BUFFER_BIT);
154871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
154971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    mST->updateTexImage();
155071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden
155171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    buf = mST->getCurrentBuffer();
155271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    ASSERT_EQ((uint32_t) 0, mST->getCurrentTransform());
155371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    ASSERT_EQ(texWidth, buf->getWidth());
155471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden    ASSERT_EQ(texHeight, buf->getHeight());
155571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden}
155671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden
15576f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
15581876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texWidth = 64;
15591876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    const int texHeight = 64;
15601876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15611876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    mST->setDefaultBufferSize(texWidth, texHeight);
15621876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15634697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis    // This test requires 3 buffers to complete run on a single thread.
15644697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis    mST->setDefaultMaxBufferCount(3);
15654697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis
15661876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    // Do the producer side of things
15676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
15686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis            mProducerEglSurface, mProducerEglContext));
15691876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
15701876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // This is needed to ensure we pick up a buffer of the correct size.
15726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
15731876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15741876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
15751876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
15761876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15771876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glEnable(GL_SCISSOR_TEST);
15781876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(4, 4, 4, 4);
15791876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
15801876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
15811876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15821876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(24, 48, 4, 4);
15831876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.0, 1.0, 0.0, 1.0);
15841876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
15851876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15861876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glScissor(37, 17, 4, 4);
15871876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.0, 0.0, 1.0, 1.0);
15881876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
15891876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15906f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
15911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    // Do the consumer side of things
15931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
15941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis            mEglContext));
15951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
15961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
15971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glDisable(GL_SCISSOR_TEST);
15981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1599d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    // Skip the first frame, which was empty
1600d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
1601d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
16021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
16031876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
16041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
16051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
1606c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis    glViewport(0, 0, texWidth, texHeight);
16071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    drawTexture();
16081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
16091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
16101876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
16111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
16121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
16131876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
16141876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
16151876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
16161876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
16171876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
16181876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
16191876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
16201876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
16211876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
16221876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
16231876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
16241876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
16251876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
16261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
16271876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
16281876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
16291876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
16301876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis}
16311876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis
16326f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
1633fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    sp<GraphicBuffer> buffers[2];
1634fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis
1635e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // This test requires async mode to run on a single thread.
1636e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1637e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis            mProducerEglSurface, mProducerEglContext));
1638e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1639e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
1640e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
16417b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1642fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    for (int i = 0; i < 2; i++) {
16436f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        // Produce a frame
16446f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
16456f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mProducerEglSurface, mProducerEglContext));
16466f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
16476f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
16486f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        eglSwapBuffers(mEglDisplay, mProducerEglSurface);
16497b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
16506f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        // Consume a frame
16516f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
16526f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mEglContext));
16536f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
1654efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis        mFW->waitForFrame();
1655d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
16566f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        buffers[i] = mST->getCurrentBuffer();
16576f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
16587b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
16596f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Destroy the GL texture object to release its ref on buffers[2].
16606f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    GLuint texID = TEX_ID;
16616f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    glDeleteTextures(1, &texID);
16627b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
16636f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Destroy the EGLSurface
16646f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
16656f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1666fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mProducerEglSurface = EGL_NO_SURFACE;
16677b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1668fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    // This test should have the only reference to buffer 0.
16696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(1, buffers[0]->getStrongCount());
16707b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
16712adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    // The GLConsumer should hold a single reference to buffer 1 in its
1672fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    // mCurrentBuffer member.  All of the references in the slots should have
1673fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    // been released.
1674fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    EXPECT_EQ(2, buffers[1]->getStrongCount());
16756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis}
16767b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
16776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
16786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    sp<GraphicBuffer> buffers[3];
16797b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
1680e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // This test requires async mode to run on a single thread.
1681e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1682e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis            mProducerEglSurface, mProducerEglContext));
1683e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1684e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
1685e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
16867b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
16876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    for (int i = 0; i < 3; i++) {
16886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        // Produce a frame
16896f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
16906f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mProducerEglSurface, mProducerEglContext));
16916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
16926f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
16936f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
16946f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
16957b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
16966f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        // Consume a frame
16976f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
16986f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis                mEglContext));
16996f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
1700efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis        mFW->waitForFrame();
17016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
17026f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        buffers[i] = mST->getCurrentBuffer();
17036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    }
17047b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
17052adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    // Abandon the GLConsumer, releasing the ref that the GLConsumer has
17066f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // on buffers[2].
17077b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis    mST->abandon();
17087b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
17096f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Destroy the GL texture object to release its ref on buffers[2].
17106f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    GLuint texID = TEX_ID;
17116f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    glDeleteTextures(1, &texID);
17127b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
17136f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    // Destroy the EGLSurface.
17146f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
17156f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1716fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis    mProducerEglSurface = EGL_NO_SURFACE;
17177b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
17186f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(1, buffers[0]->getStrongCount());
17196f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis    EXPECT_EQ(1, buffers[1]->getStrongCount());
1720e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis
1721e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // Depending on how lazily the GL driver dequeues buffers, we may end up
1722e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // with either two or three total buffers.  If there are three, make sure
1723e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    // the last one was properly down-ref'd.
1724e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    if (buffers[2] != buffers[0]) {
1725e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis        EXPECT_EQ(1, buffers[2]->getStrongCount());
1726e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis    }
17277b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis}
17287b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis
17297589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias AgopianTEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentBeforeConsumerDeathUnrefsBuffers) {
17307589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    sp<GraphicBuffer> buffer;
17317589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17327589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
17337589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian            mProducerEglSurface, mProducerEglContext));
17347589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17357589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Produce a frame
17367589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
17377589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
17387589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    ASSERT_EQ(EGL_SUCCESS, eglGetError());
17397589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17407589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Destroy the EGLSurface.
17417589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
17427589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    ASSERT_EQ(EGL_SUCCESS, eglGetError());
17437589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mProducerEglSurface = EGL_NO_SURFACE;
17447589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mSTC.clear();
17457589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mANW.clear();
17467589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mTextureRenderer.clear();
17477589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17487589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Consume a frame
17497589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
17507589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    buffer = mST->getCurrentBuffer();
17517589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17527589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Destroy the GL texture object to release its ref
17537589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    GLuint texID = TEX_ID;
17547589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    glDeleteTextures(1, &texID);
17557589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17567589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // make un-current, all references to buffer should be gone
17577589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
17587589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian            EGL_NO_SURFACE, EGL_NO_CONTEXT));
17597589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17607589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Destroy consumer
17617589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mST.clear();
17627589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17637589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_EQ(1, buffer->getStrongCount());
17647589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian}
17657589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17667589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias AgopianTEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentAfterConsumerDeathUnrefsBuffers) {
17677589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    sp<GraphicBuffer> buffer;
17687589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17697589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
17707589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian            mProducerEglSurface, mProducerEglContext));
17717589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17727589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Produce a frame
17737589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    glClear(GL_COLOR_BUFFER_BIT);
17747589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
17757589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    ASSERT_EQ(EGL_SUCCESS, eglGetError());
17767589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17777589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Destroy the EGLSurface.
17787589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
17797589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    ASSERT_EQ(EGL_SUCCESS, eglGetError());
17807589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mProducerEglSurface = EGL_NO_SURFACE;
17817589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mSTC.clear();
17827589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mANW.clear();
17837589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mTextureRenderer.clear();
17847589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17857589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Consume a frame
17867589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
17877589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    buffer = mST->getCurrentBuffer();
17887589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17897589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Destroy the GL texture object to release its ref
17907589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    GLuint texID = TEX_ID;
17917589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    glDeleteTextures(1, &texID);
17927589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17937589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // Destroy consumer
17947589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    mST.clear();
17957589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
17967589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    // make un-current, all references to buffer should be gone
17977589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
17987589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian            EGL_NO_SURFACE, EGL_NO_CONTEXT));
17997589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
18007589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian    EXPECT_EQ(1, buffer->getStrongCount());
18017589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian}
18027589b2a7975cc3bc2a0659ab6503ceb3e4d94048Mathias Agopian
1803c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromUserSizedGLFilledBuffer) {
1804c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texWidth = 64 };
1805c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texHeight = 64 };
1806c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
18074697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis    // This test requires 3 buffers to complete run on a single thread.
18084697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis    mST->setDefaultMaxBufferCount(3);
18094697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis
1810c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the user buffer size.
1811c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
1812c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1813c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the producer side of things
1814c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1815c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mProducerEglSurface, mProducerEglContext));
1816c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1817c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1818c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // This is needed to ensure we pick up a buffer of the correct size.
1819c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1820c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1821c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
1822c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1823c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1824c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glEnable(GL_SCISSOR_TEST);
1825c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glScissor(4, 4, 1, 1);
1826c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
1827c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1828c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1829c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1830c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1831c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the consumer side of things
1832c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
1833c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mEglContext));
1834c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1835c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1836c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glDisable(GL_SCISSOR_TEST);
1837c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1838d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    // Skip the first frame, which was empty
1839d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
1840d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
1841c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1842c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
1843c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1844c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1845c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glViewport(0, 0, texWidth, texHeight);
1846c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    drawTexture();
1847c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1848c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
1849c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
1850c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
1851c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
1852c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1853c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 4,  4, 255,   0,   0, 255));
1854c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 5,  5, 153, 153, 153, 153));
1855c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 3,  3, 153, 153, 153, 153));
1856c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(45, 52, 153, 153, 153, 153));
1857c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(12, 36, 153, 153, 153, 153));
1858c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis}
1859c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1860c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedUserSizedGLFilledBuffer) {
1861c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texWidth = 64 };
1862c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texHeight = 16 };
1863c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
18644697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis    // This test requires 3 buffers to complete run on a single thread.
18654697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis    mST->setDefaultMaxBufferCount(3);
18664697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis
1867c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the transform hint.
1868c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
1869c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1870c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the user buffer size.
1871c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
1872c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1873c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the producer side of things
1874c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1875c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mProducerEglSurface, mProducerEglContext));
1876c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1877c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1878c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // This is needed to ensure we pick up a buffer of the correct size and the
1879c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // new rotation hint.
1880c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1881c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1882c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
1883c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1884c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1885c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glEnable(GL_SCISSOR_TEST);
1886c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glScissor(24, 4, 1, 1);
1887c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
1888c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1889c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1890c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1891c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1892c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the consumer side of things
1893c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
1894c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mEglContext));
1895c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1896c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1897c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glDisable(GL_SCISSOR_TEST);
1898c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1899d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    // Skip the first frame, which was empty
1900d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
1901d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
1902c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1903c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
1904c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1905c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1906c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glViewport(0, 0, texWidth, texHeight);
1907c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    drawTexture();
1908c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1909c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
1910c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
1911c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
1912c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
1913c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1914c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
1915c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
1916c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
1917c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
1918c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
1919c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis}
1920c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1921c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedGLFilledBuffer) {
1922c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texWidth = 64 };
1923c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    enum { texHeight = 16 };
1924c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
19254697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis    // This test requires 3 buffers to complete run on a single thread.
19264697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis    mST->setDefaultMaxBufferCount(3);
19274697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis
1928c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the transform hint.
1929c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
1930c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1931c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Set the default buffer size.
1932c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    mST->setDefaultBufferSize(texWidth, texHeight);
1933c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1934c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the producer side of things
1935c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
1936c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mProducerEglSurface, mProducerEglContext));
1937c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1938c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1939c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // This is needed to ensure we pick up a buffer of the correct size and the
1940c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // new rotation hint.
1941c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1942c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1943c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.6, 0.6, 0.6, 0.6);
1944c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1945c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1946c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glEnable(GL_SCISSOR_TEST);
1947c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glScissor(24, 4, 1, 1);
1948c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(1.0, 0.0, 0.0, 1.0);
1949c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1950c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1951c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
1952c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1953c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    // Do the consumer side of things
1954c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
1955c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis            mEglContext));
1956c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
1957c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1958c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glDisable(GL_SCISSOR_TEST);
1959c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1960d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    // Skip the first frame, which was empty
1961d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
1962d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
1963c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1964c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
1965c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
1966c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1967c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    glViewport(0, 0, texWidth, texHeight);
1968c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    drawTexture();
1969c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1970c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
1971c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
1972c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
1973c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
1974c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
1975c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
1976c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
1977c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
1978c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
1979c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis    EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
1980c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis}
1981c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis
19825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis/*
19836f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * This test fixture is for testing GL -> GL texture streaming from one thread
19846f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * to another.  It contains functionality to create a producer thread that will
19856f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * perform GL rendering to an ANativeWindow that feeds frames to a
19862adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden * GLConsumer.  Additionally it supports interlocking the producer and
19876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * consumer threads so that a specific sequence of calls can be
19886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * deterministically created by the test.
19895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
19905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * The intended usage is as follows:
19915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
19925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * TEST_F(...) {
19935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     class PT : public ProducerThread {
19945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *         virtual void render() {
19955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *             ...
19965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *             swapBuffers();
19975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *         }
19985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     };
19995451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
20005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     runProducerThread(new PT());
20015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
20025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // The order of these calls will vary from test to test and may include
20035451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // multiple frames and additional operations (e.g. GL rendering from the
20045451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     // texture).
20055451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     fc->waitForFrame();
20065451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     mST->updateTexImage();
20075451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *     fc->finishFrame();
20085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * }
20095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis *
20105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis */
20116f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisclass SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
20125451d15ee209f29d64beea87583f7058dee69911Jamie Gennisprotected:
20135451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // ProducerThread is an abstract base class to simplify the creation of
20155451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // OpenGL ES frame producer threads.
20165451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class ProducerThread : public Thread {
20175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    public:
20185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual ~ProducerThread() {
20195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
20205451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void setEglObjects(EGLDisplay producerEglDisplay,
20225451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                EGLSurface producerEglSurface,
20235451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                EGLContext producerEglContext) {
20245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglDisplay = producerEglDisplay;
20255451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglSurface = producerEglSurface;
20265451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerEglContext = producerEglContext;
20275451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
20285451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20295451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual bool threadLoop() {
20305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface,
20315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                    mProducerEglSurface, mProducerEglContext);
20325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            render();
20335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
20345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                    EGL_NO_CONTEXT);
20355451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            return false;
20365451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
20375451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20385451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    protected:
20395451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() = 0;
20405451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20415451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void swapBuffers() {
20425451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface);
20435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
20445451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLDisplay mProducerEglDisplay;
20465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLSurface mProducerEglSurface;
20475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        EGLContext mProducerEglContext;
20485451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
20495451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20505451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // FrameCondition is a utility class for interlocking between the producer
20515451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // and consumer threads.  The FrameCondition object should be created and
20525451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // destroyed in the consumer thread only.  The consumer thread should set
20532adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    // the FrameCondition as the FrameAvailableListener of the GLConsumer,
20545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // and should call both waitForFrame and finishFrame once for each expected
20555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // frame.
20565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    //
20575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // This interlocking relies on the fact that onFrameAvailable gets called
20582adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    // synchronously from GLConsumer::queueBuffer.
20592adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    class FrameCondition : public GLConsumer::FrameAvailableListener {
20605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    public:
20612640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        FrameCondition():
20622640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis                mFrameAvailable(false),
20632640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis                mFrameFinished(false) {
20642640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        }
20652640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis
20665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // waitForFrame waits for the next frame to arrive.  This should be
20675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // called from the consumer thread once for every frame expected by the
20685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // test.
20695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void waitForFrame() {
20705451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
20716807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("+waitForFrame");
20722640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            while (!mFrameAvailable) {
20732640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis                mFrameAvailableCondition.wait(mMutex);
20742640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            }
20752640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            mFrameAvailable = false;
20766807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("-waitForFrame");
20775451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
20785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // Allow the producer to return from its swapBuffers call and continue
20805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // on to produce the next frame.  This should be called by the consumer
20815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // thread once for every frame expected by the test.
20825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        void finishFrame() {
20835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
20846807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("+finishFrame");
20852640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            mFrameFinished = true;
20865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mFrameFinishCondition.signal();
20876807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("-finishFrame");
20885451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
20895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
20902adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        // This should be called by GLConsumer on the producer thread.
20915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void onFrameAvailable() {
20925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            Mutex::Autolock lock(mMutex);
20936807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("+onFrameAvailable");
20942640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            mFrameAvailable = true;
20955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mFrameAvailableCondition.signal();
20962640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            while (!mFrameFinished) {
20972640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis                mFrameFinishCondition.wait(mMutex);
20982640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            }
20992640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis            mFrameFinished = false;
21006807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block            ALOGV("-onFrameAvailable");
21015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
21025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21035451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    protected:
21042640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        bool mFrameAvailable;
21052640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis        bool mFrameFinished;
21062640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis
21075451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Mutex mMutex;
21085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Condition mFrameAvailableCondition;
21095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        Condition mFrameFinishCondition;
21105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
21115451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21125451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    virtual void SetUp() {
21136f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SurfaceTextureGLToGLTest::SetUp();
21145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC = new FrameCondition();
21155451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mST->setFrameAvailableListener(mFC);
21165451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
21175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    virtual void TearDown() {
21195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        if (mProducerThread != NULL) {
21205451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            mProducerThread->requestExitAndWait();
21215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
21225451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mProducerThread.clear();
21235451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC.clear();
21246f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        SurfaceTextureGLToGLTest::TearDown();
21255451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
21265451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21275451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    void runProducerThread(const sp<ProducerThread> producerThread) {
21285451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        ASSERT_TRUE(mProducerThread == NULL);
21295451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mProducerThread = producerThread;
21305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        producerThread->setEglObjects(mEglDisplay, mProducerEglSurface,
21315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                mProducerEglContext);
21325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        producerThread->run();
21335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
21345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21355451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    sp<ProducerThread> mProducerThread;
21365451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    sp<FrameCondition> mFC;
21375451d15ee209f29d64beea87583f7058dee69911Jamie Gennis};
21385451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21396f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
21406f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        UpdateTexImageBeforeFrameFinishedCompletes) {
21415451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
21425451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
21435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
21445451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClear(GL_COLOR_BUFFER_BIT);
21455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            swapBuffers();
21465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
21475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
21485451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21495451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
21505451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21515451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->waitForFrame();
2152d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
21535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->finishFrame();
21545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
2156d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}
21575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21586f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
21596f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        UpdateTexImageAfterFrameFinishedCompletes) {
21605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
21615451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
21625451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
21635451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            glClear(GL_COLOR_BUFFER_BIT);
21645451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            swapBuffers();
21655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
21665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
21675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
21695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21705451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->waitForFrame();
21715451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    mFC->finishFrame();
2172d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
21735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
21755451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
21765451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
21786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
21795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    enum { NUM_ITERATIONS = 1024 };
21805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
21825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
21835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            for (int i = 0; i < NUM_ITERATIONS; i++) {
21845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
21855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClear(GL_COLOR_BUFFER_BIT);
21866807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("+swapBuffers");
21875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                swapBuffers();
21886807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("-swapBuffers");
21895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            }
21905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
21915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
21925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
21945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
21955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS; i++) {
21965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->waitForFrame();
21976807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("+updateTexImage");
2198d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
21996807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("-updateTexImage");
22005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->finishFrame();
22015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
22025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
22035451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
22045451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
22055451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
22066f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
22076f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
22085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    enum { NUM_ITERATIONS = 1024 };
22095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
22105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    class PT : public ProducerThread {
22115451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        virtual void render() {
22125451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            for (int i = 0; i < NUM_ITERATIONS; i++) {
22135451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
22145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                glClear(GL_COLOR_BUFFER_BIT);
22156807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("+swapBuffers");
22165451d15ee209f29d64beea87583f7058dee69911Jamie Gennis                swapBuffers();
22176807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("-swapBuffers");
22185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis            }
22195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        }
22205451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    };
22215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
22225451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    runProducerThread(new PT());
22235451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
22245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS; i++) {
22255451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->waitForFrame();
22265451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        mFC->finishFrame();
22276807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("+updateTexImage");
2228d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
22296807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("-updateTexImage");
22305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
22315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
22325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis    }
22335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}
22345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis
22356e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis// XXX: This test is disabled because it is currently hanging on some devices.
22366f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest,
22376f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis        DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
22386e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    enum { NUM_ITERATIONS = 64 };
22396e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22406e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    class PT : public ProducerThread {
22416e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        virtual void render() {
22426e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis            for (int i = 0; i < NUM_ITERATIONS; i++) {
22436e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
22446e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis                glClear(GL_COLOR_BUFFER_BIT);
22456807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("+swapBuffers");
22466e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis                swapBuffers();
22476807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block                ALOGV("-swapBuffers");
22486e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis            }
22496e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        }
22506e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    };
22516e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
225231a353da225af5329735451c761b430d82dfda1bJamie Gennis    ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
22536e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22546e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    runProducerThread(new PT());
22556e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22566e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Allow three frames to be rendered and queued before starting the
22576e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // rendering in this thread.  For the latter two frames we don't call
22586e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // updateTexImage so the next dequeue from the producer thread will block
22596e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // waiting for a frame to become available.
22606e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->waitForFrame();
22616e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->finishFrame();
22626e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22636e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // We must call updateTexImage to consume the first frame so that the
22646e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // SurfaceTexture is able to reduce the buffer count to 2.  This is because
22656e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // the GL driver may dequeue a buffer when the EGLSurface is created, and
226631a353da225af5329735451c761b430d82dfda1bJamie Gennis    // that happens before we call setDefaultMaxBufferCount.  It's possible that the
22676e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // driver does not dequeue a buffer at EGLSurface creation time, so we
22686e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // cannot rely on this to cause the second dequeueBuffer call to block.
2269d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
22706e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22716e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->waitForFrame();
22726e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->finishFrame();
22736e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->waitForFrame();
22746e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    mFC->finishFrame();
22756e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22766e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
22776e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // block waiting for a buffer to become available.
22786e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    usleep(100000);
22796e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22806e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Render and present a number of images.  This thread should not be blocked
22816e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // by the fact that the producer thread is blocking in dequeue.
22826e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS; i++) {
22836e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        glClear(GL_COLOR_BUFFER_BIT);
22846e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        eglSwapBuffers(mEglDisplay, mEglSurface);
22856e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    }
22866e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22876e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Consume the two pending buffers to unblock the producer thread.
2288d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
2289d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
22906e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
22916e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    // Consume the remaining buffers from the producer thread.
22926e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    for (int i = 0; i < NUM_ITERATIONS-3; i++) {
22936e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        mFC->waitForFrame();
22946e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis        mFC->finishFrame();
22956807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("+updateTexImage");
2296d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
22976807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block        ALOGV("-updateTexImage");
22986e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis    }
22996e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis}
23006e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis
2301fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisclass SurfaceTextureFBOTest : public SurfaceTextureGLTest {
2302fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisprotected:
2303fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2304fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    virtual void SetUp() {
2305fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        SurfaceTextureGLTest::SetUp();
2306fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2307fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glGenFramebuffers(1, &mFbo);
2308fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
2309fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2310fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glGenTextures(1, &mFboTex);
2311fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glBindTexture(GL_TEXTURE_2D, mFboTex);
2312fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(),
2313fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2314fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glBindTexture(GL_TEXTURE_2D, 0);
2315fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
2316fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2317fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
2318fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2319fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                GL_TEXTURE_2D, mFboTex, 0);
2320fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glBindFramebuffer(GL_FRAMEBUFFER, 0);
2321fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
2322fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    }
2323fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2324fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    virtual void TearDown() {
2325fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        SurfaceTextureGLTest::TearDown();
2326fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2327fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glDeleteTextures(1, &mFboTex);
2328fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        glDeleteFramebuffers(1, &mFbo);
2329fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    }
2330fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2331fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    GLuint mFbo;
2332fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    GLuint mFboTex;
2333fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis};
2334fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2335fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis// This test is intended to verify that proper synchronization is done when
2336fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis// rendering into an FBO.
2337fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie GennisTEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
2338fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    const int texWidth = 64;
2339fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    const int texHeight = 64;
2340fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2341fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
2342fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
2343fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
2344fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
2345fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2346fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    android_native_buffer_t* anb;
2347d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
2348d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            &anb));
2349fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_TRUE(anb != NULL);
2350fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2351fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2352fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2353fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    // Fill the buffer with green
2354fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    uint8_t* img = NULL;
2355fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2356fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
2357fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis            0, 255);
2358fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    buf->unlock();
2359d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
2360d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis            -1));
2361fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2362fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
2363fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2364fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
2365fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    drawTexture();
2366fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    glBindFramebuffer(GL_FRAMEBUFFER, 0);
2367fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2368fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    for (int i = 0; i < 4; i++) {
2369fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        SCOPED_TRACE(String8::format("frame %d", i).string());
2370fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2371d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
2372d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                &anb));
2373fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_TRUE(anb != NULL);
2374fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2375fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        buf = new GraphicBuffer(anb, false);
2376fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2377fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        // Fill the buffer with red
2378fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
2379fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                (void**)(&img)));
2380fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
2381fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis                0, 255);
2382fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, buf->unlock());
2383fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
2384d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis                buf->getNativeBuffer(), -1));
2385fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2386fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
2387fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2388fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        drawTexture();
2389fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2390fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis        EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
2391fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    }
2392fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2393fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
2394fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2395fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis    EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
2396fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis}
2397fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis
2398ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisclass SurfaceTextureMultiContextGLTest : public SurfaceTextureGLTest {
2399ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisprotected:
240074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    enum { SECOND_TEX_ID = 123 };
240174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    enum { THIRD_TEX_ID = 456 };
240274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
2403ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    SurfaceTextureMultiContextGLTest():
2404ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis            mSecondEglContext(EGL_NO_CONTEXT) {
2405ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    }
2406ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2407ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    virtual void SetUp() {
2408ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        SurfaceTextureGLTest::SetUp();
2409ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
241074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        // Set up the secondary context and texture renderer.
2411ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        mSecondEglContext = eglCreateContext(mEglDisplay, mGlConfig,
2412ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis                EGL_NO_CONTEXT, getContextAttribs());
2413ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
2414ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mSecondEglContext);
241574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
241674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
241774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mSecondEglContext));
241874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
241974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mSecondTextureRenderer = new TextureRenderer(SECOND_TEX_ID, mST);
242074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(mSecondTextureRenderer->SetUp());
242174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
242274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        // Set up the tertiary context and texture renderer.
242374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mThirdEglContext = eglCreateContext(mEglDisplay, mGlConfig,
242474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                EGL_NO_CONTEXT, getContextAttribs());
242574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
242674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NE(EGL_NO_CONTEXT, mThirdEglContext);
242774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
242874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
242974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mThirdEglContext));
243074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_EQ(EGL_SUCCESS, eglGetError());
243174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        mThirdTextureRenderer = new TextureRenderer(THIRD_TEX_ID, mST);
243274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_NO_FATAL_FAILURE(mThirdTextureRenderer->SetUp());
243374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
243474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        // Switch back to the primary context to start the tests.
243574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
243674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis                mEglContext));
2437ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    }
2438ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2439ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    virtual void TearDown() {
244074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        if (mThirdEglContext != EGL_NO_CONTEXT) {
244174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            eglDestroyContext(mEglDisplay, mThirdEglContext);
244274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        }
2443ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        if (mSecondEglContext != EGL_NO_CONTEXT) {
2444ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis            eglDestroyContext(mEglDisplay, mSecondEglContext);
2445ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        }
2446ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis        SurfaceTextureGLTest::TearDown();
2447ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    }
2448ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2449ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    EGLContext mSecondEglContext;
245074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<TextureRenderer> mSecondTextureRenderer;
245174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
245274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EGLContext mThirdEglContext;
245374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    sp<TextureRenderer> mThirdTextureRenderer;
2454ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis};
2455ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2456ce561372186c7549a8a5fe996ac5965cda087007Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, UpdateFromMultipleContextsFails) {
2457ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
2458ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2459ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    // Latch the texture contents on the primary context.
2460efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
246174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
2462ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
2463ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    // Attempt to latch the texture on the secondary context.
246474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
246574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
246674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
246774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
246874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
246974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
247074bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextSucceeds) {
247174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
247274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
247374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2474efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
247574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
247674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
247774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
247874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
247974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
248074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Check that the GL texture was deleted.
248174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
248274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
248374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
248474bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
248574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        DetachFromContextSucceedsAfterProducerDisconnect) {
248674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
248774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
248874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2489efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
249074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
249174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
249274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
249374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
249474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
249574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
249674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Check that the GL texture was deleted.
249774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
249874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
249974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
250074bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenAbandoned) {
250174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
250274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
250374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2504efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
250574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
250674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
250774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to detach from the primary context.
250874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->abandon();
250974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(NO_INIT, mST->detachFromContext());
251074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
251174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
251274bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenDetached) {
251374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
251474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
251574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2516efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
251774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
251874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
251974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
252074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
252174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
252274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to detach from the primary context again.
252374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
252474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
252574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
252674bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoDisplay) {
252774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
252874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
252974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2530efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
253174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
253274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
253374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Make there be no current display.
253474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
253574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            EGL_NO_CONTEXT));
253674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
253774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
253874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to detach from the primary context.
253974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
254074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
254174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
254274bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoContext) {
254374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
254474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
254574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2546efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
254774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
254874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
254974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Make current context be incorrect.
255074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
2551ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis            mSecondEglContext));
2552ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
255374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
255474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to detach from the primary context.
255574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
255674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
255774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
255874bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, UpdateTexImageFailsWhenDetached) {
255974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
256074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
256174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
256274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
256374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
256474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to latch the texture contents on the primary context.
2565efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
256674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
256774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
256874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
256974bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceeds) {
257074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
257174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
257274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2573efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
257474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
257574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
257674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
257774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
257874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
257974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
258074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
258174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
258274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
258374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
258474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
258574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
258674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
258774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(SECOND_TEX_ID, texBinding);
258874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
258974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the secondary context.
259074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
259174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
259274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
259374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mSecondTextureRenderer->drawTexture();
259474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
259574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
259674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
259774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
259874bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
259974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        AttachToContextSucceedsAfterProducerDisconnect) {
260074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
260174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
260274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2603efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
260474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
260574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
260674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
260774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
260874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
260974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
261074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
261174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
261274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
261374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
261474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
261574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
261674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
261774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
261874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(SECOND_TEX_ID, texBinding);
261974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
262074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the secondary context.
262174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
262274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
262374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
262474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mSecondTextureRenderer->drawTexture();
262574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
262674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
262774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
262874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
262974bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
263074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        AttachToContextSucceedsBeforeUpdateTexImage) {
263174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
263274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
263374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
263474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
263574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
263674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
263774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
263874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
263974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
264074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
264174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
264274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
264374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
264474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
264574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(SECOND_TEX_ID, texBinding);
264674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
264774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2648efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
264974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
265074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
265174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the secondary context.
265274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
265374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
265474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
265574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mSecondTextureRenderer->drawTexture();
265674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
265774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
265874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
265974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
266074bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAbandoned) {
266174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
266274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
266374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2664efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
266574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
266674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
266774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
266874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
266974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
267074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach to the secondary context.
267174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mST->abandon();
267274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
267374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach to the primary context.
267474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(NO_INIT, mST->attachToContext(SECOND_TEX_ID));
267574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
267674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
267774bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAttached) {
267874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
267974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
268074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2681efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
268274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
268374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
268474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach to the primary context.
268574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
268674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
268774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
268874bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
268974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        AttachToContextFailsWhenAttachedBeforeUpdateTexImage) {
269074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
269174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
269274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach to the primary context.
269374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
269474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
269574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
269674bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWithNoDisplay) {
269774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
269874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
269974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2700efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
270174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
270274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
270374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
270474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
270574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
270674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Make there be no current display.
270774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
270874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            EGL_NO_CONTEXT));
270974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(EGL_SUCCESS, eglGetError());
271074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
271174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attempt to attach with no context current.
271274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
271374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
271474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
271574bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceedsTwice) {
271674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
271774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
271874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the primary context.
2719efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
272074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
272174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
272274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
272374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
272474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
272574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
272674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
272774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
272874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
272974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
273074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the secondary context.
273174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
273274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
273374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the tertiary context.
273474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
273574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mThirdEglContext));
273674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
273774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
273874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
273974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
274074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
274174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(THIRD_TEX_ID, texBinding);
274274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
274374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the tertiary context.
274474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
274574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
274674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
274774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mThirdTextureRenderer->drawTexture();
274874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
274974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
275074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis}
275174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
275274bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest,
275374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis        AttachToContextSucceedsTwiceBeforeUpdateTexImage) {
275474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
275574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
275674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the primary context.
275774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
275874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
275974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the secondary context.
276074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
276174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mSecondEglContext));
276274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
276374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
276474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Detach from the secondary context.
276574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->detachFromContext());
276674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
276774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Attach to the tertiary context.
276874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
276974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis            mThirdEglContext));
277074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
277174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
277274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Verify that the texture object was created and bound.
277374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    GLint texBinding = -1;
277474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
277574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    EXPECT_EQ(THIRD_TEX_ID, texBinding);
277674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
277774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Latch the texture contents on the tertiary context.
2778efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis    mFW->waitForFrame();
277974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(OK, mST->updateTexImage());
278074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis
278174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    // Try to use the texture from the tertiary context.
278274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClearColor(0.2, 0.2, 0.2, 0.2);
278374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glClear(GL_COLOR_BUFFER_BIT);
278474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    glViewport(0, 0, 1, 1);
278574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    mThirdTextureRenderer->drawTexture();
278674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
278774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
2788ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis}
2789ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis
279090ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse HallTEST_F(SurfaceTextureMultiContextGLTest,
279190ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall        UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
279231a353da225af5329735451c761b430d82dfda1bJamie Gennis    ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
279390ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall
279490ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    // produce two frames and consume them both on the primary context
279590ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
279690ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    mFW->waitForFrame();
279790ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_EQ(OK, mST->updateTexImage());
279890ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall
279990ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
280090ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    mFW->waitForFrame();
280190ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_EQ(OK, mST->updateTexImage());
280290ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall
280390ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    // produce one more frame
280490ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
280590ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall
280690ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    // Detach from the primary context and attach to the secondary context
280790ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_EQ(OK, mST->detachFromContext());
280890ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
280990ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall            mSecondEglContext));
281090ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
281190ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall
281290ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    // Consume final frame on secondary context
281390ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    mFW->waitForFrame();
281490ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall    ASSERT_EQ(OK, mST->updateTexImage());
281590ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall}
281690ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall
28175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis} // namespace android
2818