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