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( 869d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown String8("Test Surface"), 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 239016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ::testing::AssertionResult assertRectEq(const Rect &r1, 240016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam const Rect &r2, int tolerance=1) { 241016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 242016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam String8 msg; 243016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 244016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (abs(r1.left - r2.left) > tolerance) { 245016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam msg += String8::format("left(%d isn't %d)", r1.left, r2.left); 246016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 247016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (abs(r1.top - r2.top) > tolerance) { 248016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (!msg.isEmpty()) { 249016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam msg += " "; 250016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 251016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam msg += String8::format("top(%d isn't %d)", r1.top, r2.top); 252016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 253016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (abs(r1.right - r2.right) > tolerance) { 254016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (!msg.isEmpty()) { 255016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam msg += " "; 256016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 257016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam msg += String8::format("right(%d isn't %d)", r1.right, r2.right); 258016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 259016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (abs(r1.bottom - r2.bottom) > tolerance) { 260016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (!msg.isEmpty()) { 261016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam msg += " "; 262016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 263016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom); 264016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 265016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (!msg.isEmpty()) { 266016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]", 267016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam r1.left, r1.top, r1.right, r1.bottom, 268016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam r2.left, r2.top, r2.right, r2.bottom); 269016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam fprintf(stderr, "assertRectEq: %s\n", msg.string()); 270016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return ::testing::AssertionFailure( 271016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ::testing::Message(msg.string())); 272016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else { 273016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return ::testing::AssertionSuccess(); 274016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 275016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 276016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 277d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int mDisplaySecs; 278d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sp<SurfaceComposerClient> mComposerClient; 279d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sp<SurfaceControl> mSurfaceControl; 280d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 281d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EGLDisplay mEglDisplay; 282d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EGLSurface mEglSurface; 283d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EGLContext mEglContext; 2841876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EGLConfig mGlConfig; 285d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}; 286d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 28774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic void loadShader(GLenum shaderType, const char* pSource, 28874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLuint* outShader) { 28974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLuint shader = glCreateShader(shaderType); 29074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 29174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (shader) { 29274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glShaderSource(shader, 1, &pSource, NULL); 29374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 29474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glCompileShader(shader); 29574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 29674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint compiled = 0; 29774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 29874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 29974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!compiled) { 30074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint infoLen = 0; 30174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 30274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 30374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (infoLen) { 30474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis char* buf = (char*) malloc(infoLen); 30574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (buf) { 30674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetShaderInfoLog(shader, infoLen, NULL, buf); 30774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis printf("Shader compile log:\n%s\n", buf); 30874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis free(buf); 30974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis FAIL(); 31074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 31174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } else { 31274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis char* buf = (char*) malloc(0x1000); 31374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (buf) { 31474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetShaderInfoLog(shader, 0x1000, NULL, buf); 31574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis printf("Shader compile log:\n%s\n", buf); 31674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis free(buf); 31774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis FAIL(); 31874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 31974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 32074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteShader(shader); 32174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis shader = 0; 32274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 32374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 32474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(shader != 0); 32574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis *outShader = shader; 32674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 32774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 32874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic void createProgram(const char* pVertexSource, 32974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis const char* pFragmentSource, GLuint* outPgm) { 33074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLuint vertexShader, fragmentShader; 33174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis { 33274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis SCOPED_TRACE("compiling vertex shader"); 33374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource, 33474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis &vertexShader)); 33574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 33674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis { 33774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis SCOPED_TRACE("compiling fragment shader"); 33874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource, 33974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis &fragmentShader)); 34074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 34174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 34274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLuint program = glCreateProgram(); 34374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 34474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (program) { 34574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glAttachShader(program, vertexShader); 34674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 34774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glAttachShader(program, fragmentShader); 34874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 34974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glLinkProgram(program); 35074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint linkStatus = GL_FALSE; 35174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 35274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (linkStatus != GL_TRUE) { 35374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint bufLength = 0; 35474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 35574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (bufLength) { 35674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis char* buf = (char*) malloc(bufLength); 35774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (buf) { 35874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetProgramInfoLog(program, bufLength, NULL, buf); 35974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis printf("Program link log:\n%s\n", buf); 36074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis free(buf); 36174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis FAIL(); 36274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 36374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 36474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteProgram(program); 36574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis program = 0; 36674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 36774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 36874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteShader(vertexShader); 36974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteShader(fragmentShader); 37074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(program != 0); 37174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis *outPgm = program; 37274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 37374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 37474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatic int abs(int value) { 37574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return value > 0 ? value : -value; 37674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 37774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 37874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 379d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// XXX: Code above this point should live elsewhere 380d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 381d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisclass SurfaceTextureGLTest : public GLTest { 382d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisprotected: 38379e3125d56cca5aba88097b5ccd4f1e128bc8141Jamie Gennis enum { TEX_ID = 123 }; 384d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 385d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis virtual void SetUp() { 386d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis GLTest::SetUp(); 387d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis mST = new SurfaceTexture(TEX_ID); 388d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis mSTC = new SurfaceTextureClient(mST); 389d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis mANW = mSTC; 39074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTextureRenderer = new TextureRenderer(TEX_ID, mST); 39174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp()); 392efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW = new FrameWaiter; 393efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mST->setFrameAvailableListener(mFW); 394d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 395d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 3962640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis virtual void TearDown() { 3972640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mANW.clear(); 3982640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mSTC.clear(); 3992640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mST.clear(); 4002640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis GLTest::TearDown(); 4012640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis } 4022640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis 403d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis void drawTexture() { 40474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTextureRenderer->drawTexture(); 40574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 406d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 40774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis class TextureRenderer: public RefBase { 40874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis public: 40974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis TextureRenderer(GLuint texName, const sp<SurfaceTexture>& st): 41074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName(texName), 41174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mST(st) { 41274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 413d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 41474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis void SetUp() { 41574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis const char vsrc[] = 41674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "attribute vec4 vPosition;\n" 41774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "varying vec2 texCoords;\n" 41874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "uniform mat4 texMatrix;\n" 41974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "void main() {\n" 42074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis " vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n" 42174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis " texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n" 42274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis " gl_Position = vPosition;\n" 42374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "}\n"; 42474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 42574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis const char fsrc[] = 42674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "#extension GL_OES_EGL_image_external : require\n" 42774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "precision mediump float;\n" 42874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "uniform samplerExternalOES texSampler;\n" 42974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "varying vec2 texCoords;\n" 43074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "void main() {\n" 43174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis " gl_FragColor = texture2D(texSampler, texCoords);\n" 43274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "}\n"; 43374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 43474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis { 43574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis SCOPED_TRACE("creating shader program"); 43674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(createProgram(vsrc, fsrc, &mPgm)); 43774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 4381876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 43974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mPositionHandle = glGetAttribLocation(mPgm, "vPosition"); 44074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 44174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NE(-1, mPositionHandle); 44274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler"); 44374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 44474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NE(-1, mTexSamplerHandle); 44574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix"); 44674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 44774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NE(-1, mTexMatrixHandle); 44874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 449d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 45074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // drawTexture draws the SurfaceTexture over the entire GL viewport. 45174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis void drawTexture() { 452a96b6bdea3d5ece7b1f3bcae40e9fe632ebc8f22Jamie Gennis static const GLfloat triangleVertices[] = { 45374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis -1.0f, 1.0f, 45474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis -1.0f, -1.0f, 45574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 1.0f, -1.0f, 45674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 1.0f, 1.0f, 45774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis }; 45874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, 46074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis triangleVertices); 46174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 46274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glEnableVertexAttribArray(mPositionHandle); 46374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 46474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 46574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glUseProgram(mPgm); 46674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glUniform1i(mTexSamplerHandle, 0); 46774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 46874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName); 46974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 47074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 47174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as 47274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // they're setting the defautls for that target, but when hacking 47374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // things to use GL_TEXTURE_2D they are needed to achieve the same 47474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // behavior. 47574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, 47674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GL_LINEAR); 47774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 47874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, 47974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GL_LINEAR); 48074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 48174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, 48274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GL_CLAMP_TO_EDGE); 48374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 48474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, 48574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GL_CLAMP_TO_EDGE); 48674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 48774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 48874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLfloat texMatrix[16]; 48974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mST->getTransformMatrix(texMatrix); 49074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix); 49174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 49274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 49374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 49474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 49574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 49674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLuint mTexName; 49774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis sp<SurfaceTexture> mST; 49874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLuint mPgm; 49974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint mPositionHandle; 50074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint mTexSamplerHandle; 50174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint mTexMatrixHandle; 50274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis }; 503d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 504dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis class FrameWaiter : public SurfaceTexture::FrameAvailableListener { 505dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis public: 506dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis FrameWaiter(): 507dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis mPendingFrames(0) { 508dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 509dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 510dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis void waitForFrame() { 511dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis Mutex::Autolock lock(mMutex); 512dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis while (mPendingFrames == 0) { 513dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis mCondition.wait(mMutex); 514dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 515dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis mPendingFrames--; 516dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 517dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 518dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis virtual void onFrameAvailable() { 519dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis Mutex::Autolock lock(mMutex); 520dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis mPendingFrames++; 521dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis mCondition.signal(); 522dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 523dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 524dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int mPendingFrames; 525dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis Mutex mMutex; 526dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis Condition mCondition; 527dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis }; 528dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 5299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // Note that SurfaceTexture will lose the notifications 5309abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // onBuffersReleased and onFrameAvailable as there is currently 5319abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // no way to forward the events. This DisconnectWaiter will not let the 5329abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // disconnect finish until finishDisconnect() is called. It will 5339abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // also block until a disconnect is called 5349abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam class DisconnectWaiter : public BufferQueue::ConsumerListener { 5359abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam public: 5369abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam DisconnectWaiter () : 5379abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mWaitForDisconnect(false), 5389abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mPendingFrames(0) { 5399abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 5409abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 5419abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam void waitForFrame() { 5429abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Mutex::Autolock lock(mMutex); 5439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam while (mPendingFrames == 0) { 5449abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mFrameCondition.wait(mMutex); 5459abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 5469abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mPendingFrames--; 5479abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 5489abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 5499abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam virtual void onFrameAvailable() { 5509abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Mutex::Autolock lock(mMutex); 5519abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mPendingFrames++; 5529abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mFrameCondition.signal(); 5539abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 5549abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 5559abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam virtual void onBuffersReleased() { 5569abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Mutex::Autolock lock(mMutex); 5579abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam while (!mWaitForDisconnect) { 5589abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mDisconnectCondition.wait(mMutex); 5599abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 5609abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 5619abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 5629abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam void finishDisconnect() { 5639abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Mutex::Autolock lock(mMutex); 5649abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mWaitForDisconnect = true; 5659abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mDisconnectCondition.signal(); 5669abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 5679abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 5689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam private: 5699abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Mutex mMutex; 5709abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 5719abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam bool mWaitForDisconnect; 5729abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Condition mDisconnectCondition; 5739abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 5749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam int mPendingFrames; 5759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam Condition mFrameCondition; 5769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam }; 5779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 578d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sp<SurfaceTexture> mST; 579d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sp<SurfaceTextureClient> mSTC; 580d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sp<ANativeWindow> mANW; 58174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis sp<TextureRenderer> mTextureRenderer; 582efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis sp<FrameWaiter> mFW; 583d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis}; 584d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 585d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// Fill a YV12 buffer with a multi-colored checkerboard pattern 586d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisvoid fillYV12Buffer(uint8_t* buf, int w, int h, int stride) { 587d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis const int blockWidth = w > 16 ? w / 16 : 1; 588d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis const int blockHeight = h > 16 ? h / 16 : 1; 589d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis const int yuvTexOffsetY = 0; 590d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexStrideY = stride; 591d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexOffsetV = yuvTexStrideY * h; 592d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 593d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2; 594d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexStrideU = yuvTexStrideV; 595d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis for (int x = 0; x < w; x++) { 596d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis for (int y = 0; y < h; y++) { 597d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int parityX = (x / blockWidth) & 1; 598d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int parityY = (y / blockHeight) & 1; 599d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis unsigned char intensity = (parityX ^ parityY) ? 63 : 191; 600d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity; 601d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (x < w / 2 && y < h / 2) { 602d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity; 603d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (x * 2 < w / 2 && y * 2 < h / 2) { 604d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] = 605d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] = 606d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] = 607d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = 608d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis intensity; 609d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 610d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 611d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 612d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 613d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis} 614d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 615d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis// Fill a YV12 buffer with red outside a given rectangle and green inside it. 616d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennisvoid fillYV12BufferRect(uint8_t* buf, int w, int h, int stride, 617d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis const android_native_rect_t& rect) { 618d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis const int yuvTexOffsetY = 0; 619d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexStrideY = stride; 620d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexOffsetV = yuvTexStrideY * h; 621d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 622d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2; 623d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int yuvTexStrideU = yuvTexStrideV; 624d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis for (int x = 0; x < w; x++) { 625d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis for (int y = 0; y < h; y++) { 626d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis bool inside = rect.left <= x && x < rect.right && 627d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis rect.top <= y && y < rect.bottom; 628d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64; 629d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (x < w / 2 && y < h / 2) { 630d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis bool inside = rect.left <= 2*x && 2*x < rect.right && 631d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis rect.top <= 2*y && 2*y < rect.bottom; 632d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16; 633d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = 634d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis inside ? 16 : 255; 635d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 636d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 637d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 638d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis} 639d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 6401876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennisvoid fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) { 6411876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const size_t PIXEL_SIZE = 4; 6421876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis for (int x = 0; x < w; x++) { 6431876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis for (int y = 0; y < h; y++) { 6441876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis off_t offset = (y * stride + x) * PIXEL_SIZE; 6451876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis for (int c = 0; c < 4; c++) { 6461876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis int parityX = (x / (1 << (c+2))) & 1; 6471876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis int parityY = (y / (1 << (c+2))) & 1; 6481876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis buf[offset + c] = (parityX ^ parityY) ? 231 : 35; 6491876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis } 6501876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis } 6511876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis } 6521876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis} 6531876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 654fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisvoid fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r, 655fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis uint8_t g, uint8_t b, uint8_t a) { 656fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis const size_t PIXEL_SIZE = 4; 657fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis for (int y = 0; y < h; y++) { 658fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis for (int x = 0; x < h; x++) { 659fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis off_t offset = (y * stride + x) * PIXEL_SIZE; 660fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis buf[offset + 0] = r; 661fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis buf[offset + 1] = g; 662fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis buf[offset + 2] = b; 663fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis buf[offset + 3] = a; 664fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis } 665fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis } 666fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis} 667fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 668ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// Produce a single RGBA8 frame by filling a buffer with a checkerboard pattern 669ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// using the CPU. This assumes that the ANativeWindow is already configured to 670ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// allow this to be done (e.g. the format is set to RGBA8). 671ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// 672ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis// Calls to this function should be wrapped in an ASSERT_NO_FATAL_FAILURE(). 673ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisvoid produceOneRGBA8Frame(const sp<ANativeWindow>& anw) { 674ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis android_native_buffer_t* anb; 675d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(), 676d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 677ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_TRUE(anb != NULL); 678ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 679ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 680ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 681ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis uint8_t* img = NULL; 682ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, 683ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis (void**)(&img))); 684ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis fillRGBA8Buffer(img, buf->getWidth(), buf->getHeight(), buf->getStride()); 685ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_EQ(NO_ERROR, buf->unlock()); 686d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf->getNativeBuffer(), 687d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis -1)); 688ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis} 689ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 690d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) { 6911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texWidth = 64; 6921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texHeight = 66; 693d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 694d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 6951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); 696d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 697d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 698d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 699697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* anb; 700d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 701d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 702d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_TRUE(anb != NULL); 703d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 704d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 705d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 706d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // Fill the buffer with the a checkerboard pattern 707d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis uint8_t* img = NULL; 708d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 7091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis fillYV12Buffer(img, texWidth, texHeight, buf->getStride()); 710d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf->unlock(); 711d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), 712d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis -1)); 713d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 714d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 715d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 716d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 717d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 718d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 719c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis glViewport(0, 0, texWidth, texHeight); 720d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis drawTexture(); 721d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 722d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 255, 127, 255, 255)); 723d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(63, 0, 0, 133, 0, 255)); 724c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel(63, 65, 0, 133, 0, 255)); 725c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255)); 726d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 727c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255)); 728c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255)); 729c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel(52, 51, 98, 255, 73, 255)); 730d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel( 7, 31, 155, 0, 118, 255)); 731c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel(31, 9, 107, 24, 87, 255)); 732d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255)); 733d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(36, 22, 155, 29, 0, 255)); 734d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis} 735d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 736d05bb2ed4c99894965134994cf23c9e47274f56eJamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) { 7371876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texWidth = 64; 7381876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texHeight = 64; 739d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 740d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 7411876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); 742d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 743d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 744d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 745697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* anb; 746d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 747d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 748d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_TRUE(anb != NULL); 749d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 750d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 751d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 752d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // Fill the buffer with the a checkerboard pattern 753d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis uint8_t* img = NULL; 754d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 7551876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis fillYV12Buffer(img, texWidth, texHeight, buf->getStride()); 756d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf->unlock(); 757d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), 758d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis -1)); 759d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 760d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 761d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 762d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 763d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 764d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 765c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis glViewport(0, 0, texWidth, texHeight); 766d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis drawTexture(); 767d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 768d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 0, 133, 0, 255)); 769d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel(63, 0, 255, 127, 255, 255)); 770d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(63, 63, 0, 133, 0, 255)); 771d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255)); 772d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 773d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel(22, 19, 100, 255, 74, 255)); 774d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel(45, 11, 100, 255, 74, 255)); 775d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel(52, 12, 155, 0, 181, 255)); 776d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255)); 777d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel(31, 54, 0, 71, 117, 255)); 778d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel(29, 28, 0, 133, 0, 255)); 779d05bb2ed4c99894965134994cf23c9e47274f56eJamie Gennis EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255)); 780d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis} 781d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 782d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) { 7831876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texWidth = 64; 7841876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texHeight = 66; 785d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 786d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 7871876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); 788d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 789d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 790d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 791d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis android_native_rect_t crops[] = { 792d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis {4, 6, 22, 36}, 793d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis {0, 6, 22, 36}, 794d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis {4, 0, 22, 36}, 7951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis {4, 6, texWidth, 36}, 7961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis {4, 6, 22, texHeight}, 797d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis }; 798d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 799d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis for (int i = 0; i < 5; i++) { 800d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis const android_native_rect_t& crop(crops[i]); 8016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", 8026f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis crop.left, crop.top, crop.right, crop.bottom).string()); 803d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 804d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop)); 805d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 806697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* anb; 807d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 808d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 809d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ASSERT_TRUE(anb != NULL); 810d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 811d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 812d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 813d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis uint8_t* img = NULL; 814d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 8151876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop); 816d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis buf->unlock(); 8176f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), 818d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis buf->getNativeBuffer(), -1)); 819d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 820d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 821d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 822d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 823d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 824d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 825c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis glViewport(0, 0, 64, 64); 826d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis drawTexture(); 827d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 828d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 82, 255, 35, 255)); 829d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(63, 0, 82, 255, 35, 255)); 830d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(63, 63, 82, 255, 35, 255)); 831d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel( 0, 63, 82, 255, 35, 255)); 832d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 833d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(25, 14, 82, 255, 35, 255)); 834d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(35, 31, 82, 255, 35, 255)); 835d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(57, 6, 82, 255, 35, 255)); 836d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel( 5, 42, 82, 255, 35, 255)); 837d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(32, 33, 82, 255, 35, 255)); 838d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(16, 26, 82, 255, 35, 255)); 839d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis EXPECT_TRUE(checkPixel(46, 51, 82, 255, 35, 255)); 840d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 841d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis} 842d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis 843dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis// This test is intended to catch synchronization bugs between the CPU-written 844dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis// and GPU-read buffers. 845dfcff4b4ef8b602ba485848b394b16d14847821eJamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) { 846dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis enum { texWidth = 16 }; 847dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis enum { texHeight = 16 }; 848dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis enum { numFrames = 1024 }; 849dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 850dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true)); 85131a353da225af5329735451c761b430d82dfda1bJamie Gennis ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2)); 852dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 853dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); 854dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 855dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis GRALLOC_USAGE_SW_WRITE_OFTEN)); 856dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 857dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis struct TestPixel { 858dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int x; 859dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int y; 860dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis }; 861dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis const TestPixel testPixels[] = { 862dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis { 4, 11 }, 863dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis { 12, 14 }, 864dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis { 7, 2 }, 865dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis }; 866dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])}; 867dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 868dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis class ProducerThread : public Thread { 869dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis public: 8706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ProducerThread(const sp<ANativeWindow>& anw, 8716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis const TestPixel* testPixels): 872dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis mANW(anw), 873dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis mTestPixels(testPixels) { 874dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 875dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 876dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis virtual ~ProducerThread() { 877dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 878dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 879dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis virtual bool threadLoop() { 880dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis for (int i = 0; i < numFrames; i++) { 881dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis ANativeWindowBuffer* anb; 882d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis if (native_window_dequeue_buffer_and_wait(mANW.get(), 883d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb) != NO_ERROR) { 884dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis return false; 885dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 886dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis if (anb == NULL) { 887dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis return false; 888dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 889dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 890dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 891dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 892dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis const int yuvTexOffsetY = 0; 893dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int stride = buf->getStride(); 894dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int yuvTexStrideY = stride; 895dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int yuvTexOffsetV = yuvTexStrideY * texHeight; 896dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 897dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2; 898dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int yuvTexStrideU = yuvTexStrideV; 899dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 900dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis uint8_t* img = NULL; 901dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 902dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 903dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // Gray out all the test pixels first, so we're more likely to 904dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // see a failure if GL is still texturing from the buffer we 905dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // just dequeued. 906dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis for (int j = 0; j < numTestPixels; j++) { 907dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int x = mTestPixels[j].x; 908dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int y = mTestPixels[j].y; 909dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis uint8_t value = 128; 910dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis img[y*stride + x] = value; 911dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 912dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 913dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // Fill the buffer with gray. 914dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis for (int y = 0; y < texHeight; y++) { 915dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis for (int x = 0; x < texWidth; x++) { 916dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128; 917dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128; 918dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128; 919dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 920dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 921dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 922dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // Set the test pixels to either white or black. 923dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis for (int j = 0; j < numTestPixels; j++) { 924dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int x = mTestPixels[j].x; 925dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int y = mTestPixels[j].y; 926dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis uint8_t value = 0; 927dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis if (j == (i % numTestPixels)) { 928dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis value = 255; 929dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 930dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis img[y*stride + x] = value; 931dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 932dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 933dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis buf->unlock(); 934d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), -1) 935dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis != NO_ERROR) { 936dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis return false; 937dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 938dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 939dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis return false; 940dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 941dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 942dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis sp<ANativeWindow> mANW; 943dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis const TestPixel* mTestPixels; 944dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis }; 945dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 946dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis sp<Thread> pt(new ProducerThread(mANW, testPixels)); 947dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis pt->run(); 948dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 949dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis glViewport(0, 0, texWidth, texHeight); 950dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 951dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 952dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 953dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 954dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // We wait for the first two frames up front so that the producer will be 955dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // likely to dequeue the buffer that's currently being textured from. 956efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 957efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 958dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 959dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis for (int i = 0; i < numFrames; i++) { 960dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis SCOPED_TRACE(String8::format("frame %d", i).string()); 961dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 962dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // We must wait for each frame to come in because if we ever do an 963dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // updateTexImage call that doesn't consume a newly available buffer 964dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // then the producer and consumer will get out of sync, which will cause 965dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // a deadlock. 966dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis if (i > 1) { 967efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 968dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 969d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 970dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis drawTexture(); 971dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 972dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis for (int j = 0; j < numTestPixels; j++) { 973dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int x = testPixels[j].x; 974dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis int y = testPixels[j].y; 975dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis uint8_t value = 0; 976dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis if (j == (i % numTestPixels)) { 977dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // We must y-invert the texture coords 978dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255)); 979dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } else { 980dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis // We must y-invert the texture coords 981dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255)); 982dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 983dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 984dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis } 985dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 986dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis pt->requestExitAndWait(); 987dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis} 988dfcff4b4ef8b602ba485848b394b16d14847821eJamie Gennis 9891f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) { 9901876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texWidth = 64; 9911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texHeight = 66; 9921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 9931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 9941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888)); 9951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 9961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 9971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 998ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 9991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 1000d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 10011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 10031876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 10041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 1005c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis glViewport(0, 0, texWidth, texHeight); 10061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis drawTexture(); 10071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35)); 10091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(63, 0, 231, 231, 231, 231)); 1010c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231)); 1011c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel( 0, 65, 35, 35, 35, 35)); 10121876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10131876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(15, 10, 35, 231, 231, 231)); 10141f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis EXPECT_TRUE(checkPixel(23, 65, 231, 35, 231, 35)); 1015c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis EXPECT_TRUE(checkPixel(19, 40, 35, 231, 35, 35)); 10161876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(38, 30, 231, 35, 35, 35)); 10171876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(42, 54, 35, 35, 35, 231)); 10181f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis EXPECT_TRUE(checkPixel(37, 34, 35, 231, 231, 231)); 10191876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(31, 8, 231, 35, 35, 231)); 10201f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis EXPECT_TRUE(checkPixel(37, 47, 231, 35, 231, 231)); 10211f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis EXPECT_TRUE(checkPixel(25, 38, 35, 35, 35, 35)); 10221f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis EXPECT_TRUE(checkPixel(49, 6, 35, 231, 35, 35)); 10231876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(54, 50, 35, 231, 231, 231)); 10241f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231)); 10251f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis EXPECT_TRUE(checkPixel(10, 6, 35, 35, 231, 231)); 10261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(29, 4, 35, 35, 35, 231)); 10271f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis EXPECT_TRUE(checkPixel(55, 28, 35, 35, 231, 35)); 10281876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(58, 55, 35, 35, 231, 231)); 10291876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis} 10301876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10311f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie GennisTEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) { 10321876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texWidth = 64; 10331876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texHeight = 64; 10341876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10351876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 10361876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888)); 10371876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 10381876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 10391876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 1040ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 10411876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 1042d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 10431876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10441876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 10451876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 10461876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 1047c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis glViewport(0, 0, texWidth, texHeight); 10481876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis drawTexture(); 10491876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10501876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 231, 231, 231, 231)); 10511876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(63, 0, 35, 35, 35, 35)); 10521876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231)); 10531876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 0, 63, 35, 35, 35, 35)); 10541876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10551876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231, 35)); 10561876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(16, 1, 231, 231, 35, 231)); 10571876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(21, 12, 231, 35, 35, 231)); 10581876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(26, 51, 231, 35, 231, 35)); 10591876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 5, 32, 35, 231, 231, 35)); 10601876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(13, 8, 35, 231, 231, 231)); 10611876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(46, 3, 35, 35, 231, 35)); 10621876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(30, 33, 35, 35, 35, 35)); 10631876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 6, 52, 231, 231, 35, 35)); 10641876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(55, 33, 35, 231, 35, 231)); 10651876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(16, 29, 35, 35, 231, 231)); 10661876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 1, 30, 35, 35, 35, 231)); 10671876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(41, 37, 35, 35, 231, 231)); 10681876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(46, 29, 231, 231, 35, 35)); 10691876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(15, 25, 35, 231, 35, 231)); 10701876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 3, 52, 35, 231, 35, 35)); 10711876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis} 10721876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 10739abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// Tests if SurfaceTexture and BufferQueue are robust enough 10749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// to handle a special case where updateTexImage is called 10759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// in the middle of disconnect. This ordering is enforced 10769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// by blocking in the disconnect callback. 10779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel LamTEST_F(SurfaceTextureGLTest, DisconnectStressTest) { 10789abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 10799abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam class ProducerThread : public Thread { 10809abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam public: 10819abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ProducerThread(const sp<ANativeWindow>& anw): 10829abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mANW(anw) { 10839abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 10849abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 10859abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam virtual ~ProducerThread() { 10869abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 10879abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 10889abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam virtual bool threadLoop() { 10899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ANativeWindowBuffer* anb; 10909abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 10919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL); 10929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 10939abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam for (int numFrames =0 ; numFrames < 2; numFrames ++) { 10949abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1095d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis if (native_window_dequeue_buffer_and_wait(mANW.get(), 1096d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb) != NO_ERROR) { 10979abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return false; 10989abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 10999abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (anb == NULL) { 11009abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return false; 11019abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 1102d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis if (mANW->queueBuffer(mANW.get(), anb, -1) 11039abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam != NO_ERROR) { 11049abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return false; 11059abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 11069abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 11079abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11089abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL); 11099abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11109abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return false; 11119abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 11129abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11139abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam private: 11149abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam sp<ANativeWindow> mANW; 11159abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam }; 11169abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11179abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ASSERT_EQ(OK, mST->setSynchronousMode(true)); 11189abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11199abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam sp<DisconnectWaiter> dw(new DisconnectWaiter()); 11209abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mST->getBufferQueue()->consumerConnect(dw); 11219abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11229abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11239abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam sp<Thread> pt(new ProducerThread(mANW)); 11249abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam pt->run(); 11259abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11269abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // eat a frame so SurfaceTexture will own an at least one slot 11279abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam dw->waitForFrame(); 11289abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam EXPECT_EQ(OK,mST->updateTexImage()); 11299abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11309abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam dw->waitForFrame(); 11319abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // Could fail here as SurfaceTexture thinks it still owns the slot 11329abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // but bufferQueue has released all slots 11339abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam EXPECT_EQ(OK,mST->updateTexImage()); 11349abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11359abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam dw->finishDisconnect(); 11369abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam} 11379abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11389abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11399abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// This test ensures that the SurfaceTexture clears the mCurrentTexture 11409abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// when it is disconnected and reconnected. Otherwise it will 11419abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam// attempt to release a buffer that it does not owned 11429abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel LamTEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) { 11439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ASSERT_EQ(OK, mST->setSynchronousMode(true)); 11449abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1145efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis ASSERT_EQ(OK, native_window_api_connect(mANW.get(), 1146efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis NATIVE_WINDOW_API_EGL)); 11479abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11489abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ANativeWindowBuffer *anb; 11499abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1150d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 1151d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 11529abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1153d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 1154d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 11559abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11569abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam EXPECT_EQ(OK,mST->updateTexImage()); 11579abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam EXPECT_EQ(OK,mST->updateTexImage()); 11589abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1159efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(), 1160efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis NATIVE_WINDOW_API_EGL)); 1161efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis ASSERT_EQ(OK, native_window_api_connect(mANW.get(), 1162efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis NATIVE_WINDOW_API_EGL)); 11639abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11649abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam ASSERT_EQ(OK, mST->setSynchronousMode(true)); 11659abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1166d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 1167d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 11689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 11699abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // Will fail here if mCurrentTexture is not cleared properly 1170efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 11719abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam EXPECT_EQ(OK,mST->updateTexImage()); 1172efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis 1173efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(), 1174efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis NATIVE_WINDOW_API_EGL)); 11759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam} 11769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 1177016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel LamTEST_F(SurfaceTextureGLTest, ScaleToWindowMode) { 1178016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, mST->setSynchronousMode(true)); 1179016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1180016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(), 1181016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)); 1182016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1183016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The producer image size 1184016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512)); 1185016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1186016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The consumer image size (16 x 9) ratio 1187016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mST->setDefaultBufferSize(1280, 720); 1188016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1189efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis ASSERT_EQ(OK, native_window_api_connect(mANW.get(), 1190efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis NATIVE_WINDOW_API_CPU)); 1191016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1192016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ANativeWindowBuffer *anb; 1193016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1194016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam android_native_rect_t odd = {23, 78, 123, 477}; 1195016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &odd)); 1196d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 1197d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 1198efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 1199d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis EXPECT_EQ(OK, mST->updateTexImage()); 1200016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect r = mST->getCurrentCrop(); 1201016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam assertRectEq(Rect(23, 78, 123, 477), r); 1202016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1203efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(), 1204efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis NATIVE_WINDOW_API_CPU)); 1205016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam} 1206016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1207016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam// This test ensures the scaling mode does the right thing 1208016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam// ie NATIVE_WINDOW_SCALING_MODE_CROP should crop 1209016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam// the image such that it has the same aspect ratio as the 1210016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam// default buffer size 1211016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel LamTEST_F(SurfaceTextureGLTest, CroppedScalingMode) { 1212016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, mST->setSynchronousMode(true)); 1213016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1214016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(), 1215016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam NATIVE_WINDOW_SCALING_MODE_SCALE_CROP)); 1216016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1217016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The producer image size 1218016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512)); 1219016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1220016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The consumer image size (16 x 9) ratio 1221016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mST->setDefaultBufferSize(1280, 720); 1222016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1223016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU); 1224016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1225016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ANativeWindowBuffer *anb; 1226016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1227016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is in the shape of (320, 180) === 16 x 9 1228016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam android_native_rect_t standard = {10, 20, 330, 200}; 1229016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &standard)); 1230d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 1231d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 1232efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 1233d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis EXPECT_EQ(OK, mST->updateTexImage()); 1234016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect r = mST->getCurrentCrop(); 1235016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // crop should be the same as crop (same aspect ratio) 1236016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam assertRectEq(Rect(10, 20, 330, 200), r); 1237016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1238016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // make this wider then desired aspect 239 x 100 (2.39:1) 1239016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam android_native_rect_t wide = {20, 30, 259, 130}; 1240016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &wide)); 1241d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 1242d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 1243efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 1244d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis EXPECT_EQ(OK, mST->updateTexImage()); 1245016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam r = mST->getCurrentCrop(); 1246016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // crop should be the same height, but have cropped left and right borders 1247016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // offset is 30.6 px L+, R- 1248016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam assertRectEq(Rect(51, 30, 228, 130), r); 1249016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1250016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // This image is taller then desired aspect 400 x 300 (4:3) 1251016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam android_native_rect_t narrow = {0, 0, 400, 300}; 1252016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &narrow)); 1253d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb)); 1254d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1)); 1255efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 1256d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis EXPECT_EQ(OK, mST->updateTexImage()); 1257016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam r = mST->getCurrentCrop(); 1258016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // crop should be the same width, but have cropped top and bottom borders 1259016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // offset is 37.5 px 1260016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam assertRectEq(Rect(0, 37, 400, 262), r); 1261016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 1262016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU); 1263016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam} 1264016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 12656f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) { 12666f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis class ProducerThread : public Thread { 12676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis public: 12686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ProducerThread(const sp<ANativeWindow>& anw): 12696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mANW(anw), 12706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mDequeueError(NO_ERROR) { 12716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 12726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 12736f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis virtual ~ProducerThread() { 12746f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 12756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 12766f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis virtual bool threadLoop() { 12776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis Mutex::Autolock lock(mMutex); 12786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ANativeWindowBuffer* anb; 12796f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 12806f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Frame 1 1281d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis if (native_window_dequeue_buffer_and_wait(mANW.get(), 1282d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb) != NO_ERROR) { 12836f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis return false; 12846f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 12856f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis if (anb == NULL) { 12866f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis return false; 12876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 1288d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis if (mANW->queueBuffer(mANW.get(), anb, -1) 12896f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis != NO_ERROR) { 12906f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis return false; 12916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 12926f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 12936f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Frame 2 1294d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis if (native_window_dequeue_buffer_and_wait(mANW.get(), 1295d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb) != NO_ERROR) { 12966f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis return false; 12976f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 12986f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis if (anb == NULL) { 12996f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis return false; 13006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 1301d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis if (mANW->queueBuffer(mANW.get(), anb, -1) 13026f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis != NO_ERROR) { 13036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis return false; 13046f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 13056f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13066f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Frame 3 - error expected 1307d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis mDequeueError = native_window_dequeue_buffer_and_wait(mANW.get(), 1308d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb); 13096f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis return false; 13106f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 13116f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13126f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis status_t getDequeueError() { 13136f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis Mutex::Autolock lock(mMutex); 13146f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis return mDequeueError; 13156f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 13166f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13176f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis private: 13186f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis sp<ANativeWindow> mANW; 13196f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis status_t mDequeueError; 13206f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis Mutex mMutex; 13216f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis }; 13226f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13236f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(OK, mST->setSynchronousMode(true)); 132431a353da225af5329735451c761b430d82dfda1bJamie Gennis ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2)); 13256f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13266f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis sp<Thread> pt(new ProducerThread(mANW)); 13276f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis pt->run(); 13286f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 1329efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 1330efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 13316f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13326f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Sleep for 100ms to allow the producer thread's dequeueBuffer call to 13336f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // block waiting for a buffer to become available. 13346f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis usleep(100000); 13356f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13366f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mST->abandon(); 13376f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13386f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis pt->requestExitAndWait(); 13396f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(NO_INIT, 13406f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError()); 13416f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis} 13426f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13436f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) { 13446f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis int texHeight = 16; 13456f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ANativeWindowBuffer* anb; 13466f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13476f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis GLint maxTextureSize; 13486f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); 13496f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13506f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // make sure it works with small textures 13516f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mST->setDefaultBufferSize(16, texHeight); 1352d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 1353d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 13546f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(16, anb->width); 13556f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(texHeight, anb->height); 1356d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1)); 13576f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(NO_ERROR, mST->updateTexImage()); 13586f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13596f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // make sure it works with GL_MAX_TEXTURE_SIZE 13606f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mST->setDefaultBufferSize(maxTextureSize, texHeight); 1361d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 1362d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 13636f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(maxTextureSize, anb->width); 13646f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(texHeight, anb->height); 1365d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1)); 13666f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(NO_ERROR, mST->updateTexImage()); 13676f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13686f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // make sure it fails with GL_MAX_TEXTURE_SIZE+1 13696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mST->setDefaultBufferSize(maxTextureSize+1, texHeight); 1370d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 1371d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 13726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(maxTextureSize+1, anb->width); 13736f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(texHeight, anb->height); 1374d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1)); 13756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_NE(NO_ERROR, mST->updateTexImage()); 13766f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis} 13776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis/* 13796f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * This test fixture is for testing GL -> GL texture streaming. It creates an 13806f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * EGLSurface and an EGLContext for the image producer to use. 13816f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis */ 13826f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisclass SurfaceTextureGLToGLTest : public SurfaceTextureGLTest { 13836f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisprotected: 13846f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis SurfaceTextureGLToGLTest(): 13856f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mProducerEglSurface(EGL_NO_SURFACE), 13866f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mProducerEglContext(EGL_NO_CONTEXT) { 13876f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 13886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 13896f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis virtual void SetUp() { 13906f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis SurfaceTextureGLTest::SetUp(); 13916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 1392ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig, 13936f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mANW.get(), NULL); 13946f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 13956f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface); 13966f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 1397ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mProducerEglContext = eglCreateContext(mEglDisplay, mGlConfig, 13986f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EGL_NO_CONTEXT, getContextAttribs()); 13996f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 14006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext); 14016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 14026f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 14036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis virtual void TearDown() { 14046f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis if (mProducerEglContext != EGL_NO_CONTEXT) { 14056f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis eglDestroyContext(mEglDisplay, mProducerEglContext); 14066f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 14076f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis if (mProducerEglSurface != EGL_NO_SURFACE) { 14086f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis eglDestroySurface(mEglDisplay, mProducerEglSurface); 14096f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 14106f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis SurfaceTextureGLTest::TearDown(); 14116f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 14126f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 14136f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EGLSurface mProducerEglSurface; 14146f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EGLContext mProducerEglContext; 14156f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis}; 14166f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis 141771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFaddenTEST_F(SurfaceTextureGLToGLTest, TransformHintGetsRespected) { 141871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden const uint32_t texWidth = 32; 141971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden const uint32_t texHeight = 64; 142071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden 142171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mST->setDefaultBufferSize(texWidth, texHeight); 142271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90); 142371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden 142471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // This test requires 3 buffers to avoid deadlock because we're 142571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // both producer and consumer, and only using one thread. 142671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mST->setDefaultMaxBufferCount(3); 142771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden 142871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // Do the producer side of things 142971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 143071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mProducerEglSurface, mProducerEglContext)); 143171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden ASSERT_EQ(EGL_SUCCESS, eglGetError()); 143271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden 143371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // Start a buffer with our chosen size and transform hint moving 143471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // through the system. 143571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden glClear(GL_COLOR_BUFFER_BIT); // give the driver something to do 143671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden eglSwapBuffers(mEglDisplay, mProducerEglSurface); 143771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mST->updateTexImage(); // consume it 143871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // Swap again. 143971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden glClear(GL_COLOR_BUFFER_BIT); 144071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden eglSwapBuffers(mEglDisplay, mProducerEglSurface); 144171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mST->updateTexImage(); 144271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden 144371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // The current buffer should either show the effects of the transform 144471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // hint (in the form of an inverse transform), or show that the 144571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // transform hint has been ignored. 144671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden sp<GraphicBuffer> buf = mST->getCurrentBuffer(); 144771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden if (mST->getCurrentTransform() == NATIVE_WINDOW_TRANSFORM_ROT_270) { 144871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden ASSERT_EQ(texWidth, buf->getHeight()); 144971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden ASSERT_EQ(texHeight, buf->getWidth()); 145071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden } else { 145171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden ASSERT_EQ(texWidth, buf->getWidth()); 145271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden ASSERT_EQ(texHeight, buf->getHeight()); 145371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden } 145471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden 145571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden // Reset the transform hint and confirm that it takes. 145671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mST->setTransformHint(0); 145771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden glClear(GL_COLOR_BUFFER_BIT); 145871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden eglSwapBuffers(mEglDisplay, mProducerEglSurface); 145971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mST->updateTexImage(); 146071f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden glClear(GL_COLOR_BUFFER_BIT); 146171f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden eglSwapBuffers(mEglDisplay, mProducerEglSurface); 146271f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden mST->updateTexImage(); 146371f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden 146471f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden buf = mST->getCurrentBuffer(); 146571f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden ASSERT_EQ((uint32_t) 0, mST->getCurrentTransform()); 146671f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden ASSERT_EQ(texWidth, buf->getWidth()); 146771f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden ASSERT_EQ(texHeight, buf->getHeight()); 146871f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden} 146971f683ac8d28e93928a9bb1744f43264b4846e8fAndy McFadden 14706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) { 14711876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texWidth = 64; 14721876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis const int texHeight = 64; 14731876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 14741876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis mST->setDefaultBufferSize(texWidth, texHeight); 14751876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 14764697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis // This test requires 3 buffers to complete run on a single thread. 14774697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis mST->setDefaultMaxBufferCount(3); 14784697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis 14791876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis // Do the producer side of things 14806f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 14816f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mProducerEglSurface, mProducerEglContext)); 14821876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 14831876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 14846f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // This is needed to ensure we pick up a buffer of the correct size. 14856f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 14861876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 14871876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClearColor(0.6, 0.6, 0.6, 0.6); 14881876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 14891876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 14901876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glEnable(GL_SCISSOR_TEST); 14911876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glScissor(4, 4, 4, 4); 14921876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClearColor(1.0, 0.0, 0.0, 1.0); 14931876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 14941876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 14951876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glScissor(24, 48, 4, 4); 14961876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClearColor(0.0, 1.0, 0.0, 1.0); 14971876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 14981876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 14991876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glScissor(37, 17, 4, 4); 15001876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClearColor(0.0, 0.0, 1.0, 1.0); 15011876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 15021876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 15036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 15041876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 15051876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis // Do the consumer side of things 15061876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 15071876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis mEglContext)); 15081876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 15091876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 15101876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glDisable(GL_SCISSOR_TEST); 15111876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 1512d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis // Skip the first frame, which was empty 1513d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 1514d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 15151876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 15161876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 15171876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 15181876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 1519c8c5152b19e20abe76dbc63b782700ae01aa4116Jamie Gennis glViewport(0, 0, texWidth, texHeight); 15201876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis drawTexture(); 15211876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 15221876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153)); 15231876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153)); 15241876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153)); 15251876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153)); 15261876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 15271876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 4, 7, 255, 0, 0, 255)); 15281876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(25, 51, 0, 255, 0, 255)); 15291876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(40, 19, 0, 0, 255, 255)); 15301876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153)); 15311876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153)); 15321876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(13, 8, 153, 153, 153, 153)); 15331876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(46, 3, 153, 153, 153, 153)); 15341876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153)); 15351876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153)); 15361876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153)); 15371876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153)); 15381876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153)); 15391876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153)); 15401876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153)); 15411876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153)); 15421876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153)); 15431876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis} 15441876d13e45ae044d4c1f6f2ee176f52f22d8a26cJamie Gennis 15456f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) { 1546fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<GraphicBuffer> buffers[2]; 1547fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1548e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis // This test requires async mode to run on a single thread. 1549e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 1550e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis mProducerEglSurface, mProducerEglContext)); 1551e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1552e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0)); 1553e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 15547b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 1555fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis for (int i = 0; i < 2; i++) { 15566f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Produce a frame 15576f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 15586f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mProducerEglSurface, mProducerEglContext)); 15596f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 15606f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 15616f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 15627b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 15636f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Consume a frame 15646f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 15656f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mEglContext)); 15666f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1567efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 1568d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 15696f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis buffers[i] = mST->getCurrentBuffer(); 15706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 15717b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 15726f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Destroy the GL texture object to release its ref on buffers[2]. 15736f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis GLuint texID = TEX_ID; 15746f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis glDeleteTextures(1, &texID); 15757b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 15766f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Destroy the EGLSurface 15776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface)); 15786f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1579fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mProducerEglSurface = EGL_NO_SURFACE; 15807b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 1581fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // This test should have the only reference to buffer 0. 15826f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(1, buffers[0]->getStrongCount()); 15837b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 1584fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // The SurfaceTexture should hold a single reference to buffer 1 in its 1585fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // mCurrentBuffer member. All of the references in the slots should have 1586fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // been released. 1587fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis EXPECT_EQ(2, buffers[1]->getStrongCount()); 15886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis} 15897b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 15906f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) { 15916f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis sp<GraphicBuffer> buffers[3]; 15927b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 1593e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis // This test requires async mode to run on a single thread. 1594e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 1595e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis mProducerEglSurface, mProducerEglContext)); 1596e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1597e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0)); 1598e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 15997b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 16006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis for (int i = 0; i < 3; i++) { 16016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Produce a frame 16026f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 16036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mProducerEglSurface, mProducerEglContext)); 16046f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 16056f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 16066f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface)); 16076f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 16087b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 16096f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Consume a frame 16106f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 16116f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis mEglContext)); 16126f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1613efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 16146f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 16156f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis buffers[i] = mST->getCurrentBuffer(); 16166f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis } 16177b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 16186f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has 16196f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // on buffers[2]. 16207b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis mST->abandon(); 16217b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 16226f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Destroy the GL texture object to release its ref on buffers[2]. 16236f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis GLuint texID = TEX_ID; 16246f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis glDeleteTextures(1, &texID); 16257b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 16266f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis // Destroy the EGLSurface. 16276f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface)); 16286f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1629fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mProducerEglSurface = EGL_NO_SURFACE; 16307b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 16316f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(1, buffers[0]->getStrongCount()); 16326f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis EXPECT_EQ(1, buffers[1]->getStrongCount()); 1633e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis 1634e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis // Depending on how lazily the GL driver dequeues buffers, we may end up 1635e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis // with either two or three total buffers. If there are three, make sure 1636e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis // the last one was properly down-ref'd. 1637e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis if (buffers[2] != buffers[0]) { 1638e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis EXPECT_EQ(1, buffers[2]->getStrongCount()); 1639e3603d7d090ba092c76f7e1c8ace3841154ab1a1Jamie Gennis } 16407b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 16417b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 164259769469e4b9b2d8b12c020eb44b030b3927a50bJamie GennisTEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) { 164359769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis // This test requires 3 buffers to run on a single thread. 164431a353da225af5329735451c761b430d82dfda1bJamie Gennis mST->setDefaultMaxBufferCount(3); 164559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 164659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis ASSERT_TRUE(mST->isSynchronousMode()); 164759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 164859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis for (int i = 0; i < 10; i++) { 164959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis // Produce a frame 165059769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 165159769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis mProducerEglSurface, mProducerEglContext)); 165259769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 165359769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 165459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface)); 165559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 165659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 165759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis // Consume a frame 165859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 165959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis mEglContext)); 166059769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 166159769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 166259769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis } 166359769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 166459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis ASSERT_TRUE(mST->isSynchronousMode()); 16657b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 16667b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 1667c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromUserSizedGLFilledBuffer) { 1668c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis enum { texWidth = 64 }; 1669c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis enum { texHeight = 64 }; 1670c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 16714697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis // This test requires 3 buffers to complete run on a single thread. 16724697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis mST->setDefaultMaxBufferCount(3); 16734697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis 1674c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Set the user buffer size. 1675c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight); 1676c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1677c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Do the producer side of things 1678c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 1679c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mProducerEglSurface, mProducerEglContext)); 1680c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1681c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1682c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // This is needed to ensure we pick up a buffer of the correct size. 1683c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 1684c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1685c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(0.6, 0.6, 0.6, 0.6); 1686c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1687c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1688c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glEnable(GL_SCISSOR_TEST); 1689c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glScissor(4, 4, 1, 1); 1690c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(1.0, 0.0, 0.0, 1.0); 1691c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1692c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1693c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 1694c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1695c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Do the consumer side of things 1696c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 1697c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mEglContext)); 1698c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1699c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1700c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glDisable(GL_SCISSOR_TEST); 1701c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1702d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis // Skip the first frame, which was empty 1703d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 1704d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 1705c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1706c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 1707c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1708c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1709c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glViewport(0, 0, texWidth, texHeight); 1710c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis drawTexture(); 1711c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1712c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153)); 1713c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153)); 1714c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153)); 1715c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153)); 1716c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1717c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 4, 4, 255, 0, 0, 255)); 1718c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 5, 5, 153, 153, 153, 153)); 1719c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 3, 3, 153, 153, 153, 153)); 1720c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(45, 52, 153, 153, 153, 153)); 1721c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(12, 36, 153, 153, 153, 153)); 1722c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis} 1723c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1724c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedUserSizedGLFilledBuffer) { 1725c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis enum { texWidth = 64 }; 1726c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis enum { texHeight = 16 }; 1727c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 17284697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis // This test requires 3 buffers to complete run on a single thread. 17294697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis mST->setDefaultMaxBufferCount(3); 17304697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis 1731c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Set the transform hint. 1732c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90); 1733c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1734c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Set the user buffer size. 1735c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight); 1736c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1737c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Do the producer side of things 1738c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 1739c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mProducerEglSurface, mProducerEglContext)); 1740c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1741c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1742c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // This is needed to ensure we pick up a buffer of the correct size and the 1743c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // new rotation hint. 1744c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 1745c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1746c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(0.6, 0.6, 0.6, 0.6); 1747c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1748c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1749c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glEnable(GL_SCISSOR_TEST); 1750c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glScissor(24, 4, 1, 1); 1751c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(1.0, 0.0, 0.0, 1.0); 1752c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1753c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1754c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 1755c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1756c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Do the consumer side of things 1757c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 1758c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mEglContext)); 1759c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1760c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1761c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glDisable(GL_SCISSOR_TEST); 1762c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1763d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis // Skip the first frame, which was empty 1764d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 1765d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 1766c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1767c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 1768c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1769c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1770c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glViewport(0, 0, texWidth, texHeight); 1771c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis drawTexture(); 1772c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1773c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153)); 1774c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153)); 1775c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153)); 1776c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153)); 1777c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1778c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(24, 4, 255, 0, 0, 255)); 1779c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(25, 5, 153, 153, 153, 153)); 1780c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(23, 3, 153, 153, 153, 153)); 1781c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153)); 1782c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(12, 8, 153, 153, 153, 153)); 1783c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis} 1784c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1785c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie GennisTEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedGLFilledBuffer) { 1786c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis enum { texWidth = 64 }; 1787c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis enum { texHeight = 16 }; 1788c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 17894697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis // This test requires 3 buffers to complete run on a single thread. 17904697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis mST->setDefaultMaxBufferCount(3); 17914697528eac85d34b2b375ece1d4b40aebe3fa5ddJamie Gennis 1792c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Set the transform hint. 1793c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90); 1794c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1795c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Set the default buffer size. 1796c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mST->setDefaultBufferSize(texWidth, texHeight); 1797c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1798c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Do the producer side of things 1799c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface, 1800c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mProducerEglSurface, mProducerEglContext)); 1801c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1802c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1803c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // This is needed to ensure we pick up a buffer of the correct size and the 1804c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // new rotation hint. 1805c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 1806c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1807c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(0.6, 0.6, 0.6, 0.6); 1808c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1809c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1810c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glEnable(GL_SCISSOR_TEST); 1811c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glScissor(24, 4, 1, 1); 1812c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(1.0, 0.0, 0.0, 1.0); 1813c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1814c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1815c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis eglSwapBuffers(mEglDisplay, mProducerEglSurface); 1816c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1817c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis // Do the consumer side of things 1818c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 1819c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis mEglContext)); 1820c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 1821c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1822c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glDisable(GL_SCISSOR_TEST); 1823c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1824d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis // Skip the first frame, which was empty 1825d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 1826d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 1827c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1828c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 1829c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glClear(GL_COLOR_BUFFER_BIT); 1830c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1831c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis glViewport(0, 0, texWidth, texHeight); 1832c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis drawTexture(); 1833c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1834c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153)); 1835c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153)); 1836c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153)); 1837c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153)); 1838c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 1839c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(24, 4, 255, 0, 0, 255)); 1840c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(25, 5, 153, 153, 153, 153)); 1841c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(23, 3, 153, 153, 153, 153)); 1842c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153)); 1843c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis EXPECT_TRUE(checkPixel(12, 8, 153, 153, 153, 153)); 1844c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis} 1845c2c380259b2a3fbe7cee1dbd3f2e1e23e9ffd5daJamie Gennis 18465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis/* 18476f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * This test fixture is for testing GL -> GL texture streaming from one thread 18486f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * to another. It contains functionality to create a producer thread that will 18496f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * perform GL rendering to an ANativeWindow that feeds frames to a 18506f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * SurfaceTexture. Additionally it supports interlocking the producer and 18516f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * consumer threads so that a specific sequence of calls can be 18526f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis * deterministically created by the test. 18535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * 18545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * The intended usage is as follows: 18555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * 18565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * TEST_F(...) { 18575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * class PT : public ProducerThread { 18585451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * virtual void render() { 18595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * ... 18605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * swapBuffers(); 18615451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * } 18625451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * }; 18635451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * 18645451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * runProducerThread(new PT()); 18655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * 18665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * // The order of these calls will vary from test to test and may include 18675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * // multiple frames and additional operations (e.g. GL rendering from the 18685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * // texture). 18695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * fc->waitForFrame(); 18705451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * mST->updateTexImage(); 18715451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * fc->finishFrame(); 18725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * } 18735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis * 18745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis */ 18756f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennisclass SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest { 18765451d15ee209f29d64beea87583f7058dee69911Jamie Gennisprotected: 18775451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 18785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // ProducerThread is an abstract base class to simplify the creation of 18795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // OpenGL ES frame producer threads. 18805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis class ProducerThread : public Thread { 18815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis public: 18825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual ~ProducerThread() { 18835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 18845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 18855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis void setEglObjects(EGLDisplay producerEglDisplay, 18865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis EGLSurface producerEglSurface, 18875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis EGLContext producerEglContext) { 18885451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mProducerEglDisplay = producerEglDisplay; 18895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mProducerEglSurface = producerEglSurface; 18905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mProducerEglContext = producerEglContext; 18915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 18925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 18935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual bool threadLoop() { 18945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface, 18955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mProducerEglSurface, mProducerEglContext); 18965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis render(); 18975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 18985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis EGL_NO_CONTEXT); 18995451d15ee209f29d64beea87583f7058dee69911Jamie Gennis return false; 19005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis protected: 19035451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual void render() = 0; 19045451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19055451d15ee209f29d64beea87583f7058dee69911Jamie Gennis void swapBuffers() { 19065451d15ee209f29d64beea87583f7058dee69911Jamie Gennis eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface); 19075451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis EGLDisplay mProducerEglDisplay; 19105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis EGLSurface mProducerEglSurface; 19115451d15ee209f29d64beea87583f7058dee69911Jamie Gennis EGLContext mProducerEglContext; 19125451d15ee209f29d64beea87583f7058dee69911Jamie Gennis }; 19135451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // FrameCondition is a utility class for interlocking between the producer 19155451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // and consumer threads. The FrameCondition object should be created and 19165451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // destroyed in the consumer thread only. The consumer thread should set 19175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // the FrameCondition as the FrameAvailableListener of the SurfaceTexture, 19185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // and should call both waitForFrame and finishFrame once for each expected 19195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // frame. 19205451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // 19215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // This interlocking relies on the fact that onFrameAvailable gets called 19225451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // synchronously from SurfaceTexture::queueBuffer. 19235451d15ee209f29d64beea87583f7058dee69911Jamie Gennis class FrameCondition : public SurfaceTexture::FrameAvailableListener { 19245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis public: 19252640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis FrameCondition(): 19262640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mFrameAvailable(false), 19272640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mFrameFinished(false) { 19282640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis } 19292640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis 19305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // waitForFrame waits for the next frame to arrive. This should be 19315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // called from the consumer thread once for every frame expected by the 19325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // test. 19335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis void waitForFrame() { 19345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis Mutex::Autolock lock(mMutex); 19356807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+waitForFrame"); 19362640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis while (!mFrameAvailable) { 19372640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mFrameAvailableCondition.wait(mMutex); 19382640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis } 19392640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mFrameAvailable = false; 19406807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-waitForFrame"); 19415451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19425451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // Allow the producer to return from its swapBuffers call and continue 19445451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // on to produce the next frame. This should be called by the consumer 19455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // thread once for every frame expected by the test. 19465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis void finishFrame() { 19475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis Mutex::Autolock lock(mMutex); 19486807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+finishFrame"); 19492640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mFrameFinished = true; 19505451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFrameFinishCondition.signal(); 19516807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-finishFrame"); 19525451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // This should be called by SurfaceTexture on the producer thread. 19555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual void onFrameAvailable() { 19565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis Mutex::Autolock lock(mMutex); 19576807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+onFrameAvailable"); 19582640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mFrameAvailable = true; 19595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFrameAvailableCondition.signal(); 19602640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis while (!mFrameFinished) { 19612640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mFrameFinishCondition.wait(mMutex); 19622640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis } 19632640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis mFrameFinished = false; 19646807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-onFrameAvailable"); 19655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis protected: 19682640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis bool mFrameAvailable; 19692640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis bool mFrameFinished; 19702640bfd1680b1be023aae091503ffbda707e3234Jamie Gennis 19715451d15ee209f29d64beea87583f7058dee69911Jamie Gennis Mutex mMutex; 19725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis Condition mFrameAvailableCondition; 19735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis Condition mFrameFinishCondition; 19745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis }; 19755451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19765451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual void SetUp() { 19776f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis SurfaceTextureGLToGLTest::SetUp(); 19785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC = new FrameCondition(); 19795451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mST->setFrameAvailableListener(mFC); 19805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19815451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual void TearDown() { 19835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis if (mProducerThread != NULL) { 19845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mProducerThread->requestExitAndWait(); 19855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mProducerThread.clear(); 19875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC.clear(); 19886f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis SurfaceTextureGLToGLTest::TearDown(); 19895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19915451d15ee209f29d64beea87583f7058dee69911Jamie Gennis void runProducerThread(const sp<ProducerThread> producerThread) { 19925451d15ee209f29d64beea87583f7058dee69911Jamie Gennis ASSERT_TRUE(mProducerThread == NULL); 19935451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mProducerThread = producerThread; 19945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis producerThread->setEglObjects(mEglDisplay, mProducerEglSurface, 19955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mProducerEglContext); 19965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis producerThread->run(); 19975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 19985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 19995451d15ee209f29d64beea87583f7058dee69911Jamie Gennis sp<ProducerThread> mProducerThread; 20005451d15ee209f29d64beea87583f7058dee69911Jamie Gennis sp<FrameCondition> mFC; 20015451d15ee209f29d64beea87583f7058dee69911Jamie Gennis}; 20025451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20036f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest, 20046f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis UpdateTexImageBeforeFrameFinishedCompletes) { 20055451d15ee209f29d64beea87583f7058dee69911Jamie Gennis class PT : public ProducerThread { 20065451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual void render() { 20075451d15ee209f29d64beea87583f7058dee69911Jamie Gennis glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 20085451d15ee209f29d64beea87583f7058dee69911Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 20095451d15ee209f29d64beea87583f7058dee69911Jamie Gennis swapBuffers(); 20105451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 20115451d15ee209f29d64beea87583f7058dee69911Jamie Gennis }; 20125451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20135451d15ee209f29d64beea87583f7058dee69911Jamie Gennis runProducerThread(new PT()); 20145451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20155451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC->waitForFrame(); 2016d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 20175451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC->finishFrame(); 20185451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20195451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! 2020d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis} 20215451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20226f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest, 20236f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis UpdateTexImageAfterFrameFinishedCompletes) { 20245451d15ee209f29d64beea87583f7058dee69911Jamie Gennis class PT : public ProducerThread { 20255451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual void render() { 20265451d15ee209f29d64beea87583f7058dee69911Jamie Gennis glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 20275451d15ee209f29d64beea87583f7058dee69911Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 20285451d15ee209f29d64beea87583f7058dee69911Jamie Gennis swapBuffers(); 20295451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 20305451d15ee209f29d64beea87583f7058dee69911Jamie Gennis }; 20315451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20325451d15ee209f29d64beea87583f7058dee69911Jamie Gennis runProducerThread(new PT()); 20335451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20345451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC->waitForFrame(); 20355451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC->finishFrame(); 2036d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 20375451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20385451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! 20395451d15ee209f29d64beea87583f7058dee69911Jamie Gennis} 20405451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20416f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest, 20426f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis RepeatedUpdateTexImageBeforeFrameFinishedCompletes) { 20435451d15ee209f29d64beea87583f7058dee69911Jamie Gennis enum { NUM_ITERATIONS = 1024 }; 20445451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20455451d15ee209f29d64beea87583f7058dee69911Jamie Gennis class PT : public ProducerThread { 20465451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual void render() { 20475451d15ee209f29d64beea87583f7058dee69911Jamie Gennis for (int i = 0; i < NUM_ITERATIONS; i++) { 20485451d15ee209f29d64beea87583f7058dee69911Jamie Gennis glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 20495451d15ee209f29d64beea87583f7058dee69911Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 20506807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+swapBuffers"); 20515451d15ee209f29d64beea87583f7058dee69911Jamie Gennis swapBuffers(); 20526807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-swapBuffers"); 20535451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 20545451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 20555451d15ee209f29d64beea87583f7058dee69911Jamie Gennis }; 20565451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20575451d15ee209f29d64beea87583f7058dee69911Jamie Gennis runProducerThread(new PT()); 20585451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20595451d15ee209f29d64beea87583f7058dee69911Jamie Gennis for (int i = 0; i < NUM_ITERATIONS; i++) { 20605451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC->waitForFrame(); 20616807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+updateTexImage"); 2062d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 20636807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-updateTexImage"); 20645451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC->finishFrame(); 20655451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20665451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! 20675451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 20685451d15ee209f29d64beea87583f7058dee69911Jamie Gennis} 20695451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20706f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest, 20716f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis RepeatedUpdateTexImageAfterFrameFinishedCompletes) { 20725451d15ee209f29d64beea87583f7058dee69911Jamie Gennis enum { NUM_ITERATIONS = 1024 }; 20735451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20745451d15ee209f29d64beea87583f7058dee69911Jamie Gennis class PT : public ProducerThread { 20755451d15ee209f29d64beea87583f7058dee69911Jamie Gennis virtual void render() { 20765451d15ee209f29d64beea87583f7058dee69911Jamie Gennis for (int i = 0; i < NUM_ITERATIONS; i++) { 20775451d15ee209f29d64beea87583f7058dee69911Jamie Gennis glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 20785451d15ee209f29d64beea87583f7058dee69911Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 20796807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+swapBuffers"); 20805451d15ee209f29d64beea87583f7058dee69911Jamie Gennis swapBuffers(); 20816807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-swapBuffers"); 20825451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 20835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 20845451d15ee209f29d64beea87583f7058dee69911Jamie Gennis }; 20855451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20865451d15ee209f29d64beea87583f7058dee69911Jamie Gennis runProducerThread(new PT()); 20875451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20885451d15ee209f29d64beea87583f7058dee69911Jamie Gennis for (int i = 0; i < NUM_ITERATIONS; i++) { 20895451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC->waitForFrame(); 20905451d15ee209f29d64beea87583f7058dee69911Jamie Gennis mFC->finishFrame(); 20916807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+updateTexImage"); 2092d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 20936807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-updateTexImage"); 20945451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20955451d15ee209f29d64beea87583f7058dee69911Jamie Gennis // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! 20965451d15ee209f29d64beea87583f7058dee69911Jamie Gennis } 20975451d15ee209f29d64beea87583f7058dee69911Jamie Gennis} 20985451d15ee209f29d64beea87583f7058dee69911Jamie Gennis 20996e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis// XXX: This test is disabled because it is currently hanging on some devices. 21006f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie GennisTEST_F(SurfaceTextureGLThreadToGLTest, 21016f4cdfe0dbe50d1cc0ce8c03451ab261e8ea3232Jamie Gennis DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) { 21026e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis enum { NUM_ITERATIONS = 64 }; 21036e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21046e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis class PT : public ProducerThread { 21056e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis virtual void render() { 21066e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis for (int i = 0; i < NUM_ITERATIONS; i++) { 21076e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 21086e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 21096807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+swapBuffers"); 21106e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis swapBuffers(); 21116807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-swapBuffers"); 21126e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis } 21136e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis } 21146e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis }; 21156e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21166e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis ASSERT_EQ(OK, mST->setSynchronousMode(true)); 211731a353da225af5329735451c761b430d82dfda1bJamie Gennis ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2)); 21186e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21196e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis runProducerThread(new PT()); 21206e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21216e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // Allow three frames to be rendered and queued before starting the 21226e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // rendering in this thread. For the latter two frames we don't call 21236e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // updateTexImage so the next dequeue from the producer thread will block 21246e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // waiting for a frame to become available. 21256e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis mFC->waitForFrame(); 21266e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis mFC->finishFrame(); 21276e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21286e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // We must call updateTexImage to consume the first frame so that the 21296e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // SurfaceTexture is able to reduce the buffer count to 2. This is because 21306e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // the GL driver may dequeue a buffer when the EGLSurface is created, and 213131a353da225af5329735451c761b430d82dfda1bJamie Gennis // that happens before we call setDefaultMaxBufferCount. It's possible that the 21326e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // driver does not dequeue a buffer at EGLSurface creation time, so we 21336e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // cannot rely on this to cause the second dequeueBuffer call to block. 2134d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 21356e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21366e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis mFC->waitForFrame(); 21376e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis mFC->finishFrame(); 21386e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis mFC->waitForFrame(); 21396e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis mFC->finishFrame(); 21406e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21416e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // Sleep for 100ms to allow the producer thread's dequeueBuffer call to 21426e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // block waiting for a buffer to become available. 21436e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis usleep(100000); 21446e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21456e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // Render and present a number of images. This thread should not be blocked 21466e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // by the fact that the producer thread is blocking in dequeue. 21476e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis for (int i = 0; i < NUM_ITERATIONS; i++) { 21486e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 21496e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis eglSwapBuffers(mEglDisplay, mEglSurface); 21506e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis } 21516e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21526e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // Consume the two pending buffers to unblock the producer thread. 2153d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 2154d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 21556e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 21566e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis // Consume the remaining buffers from the producer thread. 21576e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis for (int i = 0; i < NUM_ITERATIONS-3; i++) { 21586e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis mFC->waitForFrame(); 21596e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis mFC->finishFrame(); 21606807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("+updateTexImage"); 2161d69097f936d9780957a51ce77335ae409b32aaa3Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 21626807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block ALOGV("-updateTexImage"); 21636e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis } 21646e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis} 21656e50219aee68ae6e76943f969374dae1b27154b3Jamie Gennis 2166fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisclass SurfaceTextureFBOTest : public SurfaceTextureGLTest { 2167fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennisprotected: 2168fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2169fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis virtual void SetUp() { 2170fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis SurfaceTextureGLTest::SetUp(); 2171fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2172fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glGenFramebuffers(1, &mFbo); 2173fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 2174fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2175fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glGenTextures(1, &mFboTex); 2176fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glBindTexture(GL_TEXTURE_2D, mFboTex); 2177fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(), 2178fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 2179fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glBindTexture(GL_TEXTURE_2D, 0); 2180fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 2181fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2182fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glBindFramebuffer(GL_FRAMEBUFFER, mFbo); 2183fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 2184fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis GL_TEXTURE_2D, mFboTex, 0); 2185fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glBindFramebuffer(GL_FRAMEBUFFER, 0); 2186fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 2187fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis } 2188fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2189fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis virtual void TearDown() { 2190fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis SurfaceTextureGLTest::TearDown(); 2191fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2192fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glDeleteTextures(1, &mFboTex); 2193fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glDeleteFramebuffers(1, &mFbo); 2194fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis } 2195fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2196fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis GLuint mFbo; 2197fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis GLuint mFboTex; 2198fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis}; 2199fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2200fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis// This test is intended to verify that proper synchronization is done when 2201fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis// rendering into an FBO. 2202fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie GennisTEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) { 2203fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis const int texWidth = 64; 2204fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis const int texHeight = 64; 2205fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2206fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 2207fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888)); 2208fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 2209fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 2210fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2211fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis android_native_buffer_t* anb; 2212d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 2213d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 2214fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_TRUE(anb != NULL); 2215fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2216fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 2217fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2218fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis // Fill the buffer with green 2219fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis uint8_t* img = NULL; 2220fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 2221fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255, 2222fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 0, 255); 2223fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis buf->unlock(); 2224d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), 2225d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis -1)); 2226fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2227fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 2228fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2229fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glBindFramebuffer(GL_FRAMEBUFFER, mFbo); 2230fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis drawTexture(); 2231fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glBindFramebuffer(GL_FRAMEBUFFER, 0); 2232fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2233fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis for (int i = 0; i < 4; i++) { 2234fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis SCOPED_TRACE(String8::format("frame %d", i).string()); 2235fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2236d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), 2237d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis &anb)); 2238fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_TRUE(anb != NULL); 2239fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2240fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis buf = new GraphicBuffer(anb, false); 2241fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2242fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis // Fill the buffer with red 2243fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, 2244fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis (void**)(&img))); 2245fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0, 2246fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 0, 255); 2247fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(NO_ERROR, buf->unlock()); 2248fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), 2249d8e812ce6fe9ae0388e98b08456e1d18b9498239Jamie Gennis buf->getNativeBuffer(), -1)); 2250fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2251fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis ASSERT_EQ(NO_ERROR, mST->updateTexImage()); 2252fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2253fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis drawTexture(); 2254fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2255fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255)); 2256fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis } 2257fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2258fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis glBindFramebuffer(GL_FRAMEBUFFER, mFbo); 2259fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2260fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255)); 2261fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis} 2262fe27e2f4688301629f38a06c34e3466c9889b3b1Jamie Gennis 2263ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisclass SurfaceTextureMultiContextGLTest : public SurfaceTextureGLTest { 2264ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennisprotected: 226574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis enum { SECOND_TEX_ID = 123 }; 226674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis enum { THIRD_TEX_ID = 456 }; 226774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 2268ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis SurfaceTextureMultiContextGLTest(): 2269ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mSecondEglContext(EGL_NO_CONTEXT) { 2270ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 2271ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 2272ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis virtual void SetUp() { 2273ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis SurfaceTextureGLTest::SetUp(); 2274ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 227574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Set up the secondary context and texture renderer. 2276ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mSecondEglContext = eglCreateContext(mEglDisplay, mGlConfig, 2277ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis EGL_NO_CONTEXT, getContextAttribs()); 2278ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 2279ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_NE(EGL_NO_CONTEXT, mSecondEglContext); 228074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 228174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 228274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondEglContext)); 228374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 228474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondTextureRenderer = new TextureRenderer(SECOND_TEX_ID, mST); 228574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(mSecondTextureRenderer->SetUp()); 228674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 228774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Set up the tertiary context and texture renderer. 228874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mThirdEglContext = eglCreateContext(mEglDisplay, mGlConfig, 228974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGL_NO_CONTEXT, getContextAttribs()); 229074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 229174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NE(EGL_NO_CONTEXT, mThirdEglContext); 229274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 229374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 229474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mThirdEglContext)); 229574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 229674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mThirdTextureRenderer = new TextureRenderer(THIRD_TEX_ID, mST); 229774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(mThirdTextureRenderer->SetUp()); 229874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 229974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Switch back to the primary context to start the tests. 230074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 230174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext)); 2302ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 2303ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 2304ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis virtual void TearDown() { 230574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mThirdEglContext != EGL_NO_CONTEXT) { 230674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis eglDestroyContext(mEglDisplay, mThirdEglContext); 230774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 2308ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis if (mSecondEglContext != EGL_NO_CONTEXT) { 2309ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis eglDestroyContext(mEglDisplay, mSecondEglContext); 2310ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 2311ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis SurfaceTextureGLTest::TearDown(); 2312ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 2313ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 2314ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis EGLContext mSecondEglContext; 231574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis sp<TextureRenderer> mSecondTextureRenderer; 231674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 231774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext mThirdEglContext; 231874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis sp<TextureRenderer> mThirdTextureRenderer; 2319ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis}; 2320ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 2321ce561372186c7549a8a5fe996ac5965cda087007Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, UpdateFromMultipleContextsFails) { 2322ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 2323ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 2324ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis // Latch the texture contents on the primary context. 2325efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 232674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 2327ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 2328ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis // Attempt to latch the texture on the secondary context. 232974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 233074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondEglContext)); 233174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 233274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage()); 233374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 233474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 233574bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextSucceeds) { 233674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 233774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 233874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2339efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 234074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 234174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 234274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 234374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 234474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 234574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Check that the GL texture was deleted. 234674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID)); 234774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 234874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 234974bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, 235074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis DetachFromContextSucceedsAfterProducerDisconnect) { 235174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 235274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 235374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2354efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 235574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 235674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 235774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 235874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU); 235974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 236074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 236174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Check that the GL texture was deleted. 236274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID)); 236374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 236474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 236574bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenAbandoned) { 236674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 236774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 236874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2369efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 237074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 237174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 237274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to detach from the primary context. 237374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mST->abandon(); 237474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(NO_INIT, mST->detachFromContext()); 237574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 237674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 237774bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenDetached) { 237874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 237974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 238074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2381efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 238274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 238374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 238474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 238574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 238674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 238774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to detach from the primary context again. 238874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext()); 238974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 239074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 239174bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoDisplay) { 239274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 239374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 239474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2395efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 239674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 239774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 239874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Make there be no current display. 239974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 240074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGL_NO_CONTEXT)); 240174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 240274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 240374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to detach from the primary context. 240474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext()); 240574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 240674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 240774bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoContext) { 240874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 240974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 241074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2411efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 241274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 241374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 241474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Make current context be incorrect. 241574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 2416ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mSecondEglContext)); 2417ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 241874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 241974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to detach from the primary context. 242074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext()); 242174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 242274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 242374bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, UpdateTexImageFailsWhenDetached) { 242474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 242574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 242674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 242774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 242874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 242974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to latch the texture contents on the primary context. 2430efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 243174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage()); 243274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 243374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 243474bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceeds) { 243574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 243674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 243774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2438efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 243974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 244074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 244174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 244274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 244374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 244474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attach to the secondary context. 244574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 244674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondEglContext)); 244774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID)); 244874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 244974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Verify that the texture object was created and bound. 245074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint texBinding = -1; 245174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding); 245274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EXPECT_EQ(SECOND_TEX_ID, texBinding); 245374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 245474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Try to use the texture from the secondary context. 245574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 245674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 245774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glViewport(0, 0, 1, 1); 245874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondTextureRenderer->drawTexture(); 245974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35)); 246074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 246174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 246274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 246374bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, 246474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis AttachToContextSucceedsAfterProducerDisconnect) { 246574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 246674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 246774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2468efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 246974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 247074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 247174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 247274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU); 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 // Verify that the texture object was created and bound. 248174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint texBinding = -1; 248274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding); 248374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EXPECT_EQ(SECOND_TEX_ID, texBinding); 248474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 248574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Try to use the texture from the secondary context. 248674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 248774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 248874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glViewport(0, 0, 1, 1); 248974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondTextureRenderer->drawTexture(); 249074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 249174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35)); 249274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 249374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 249474bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, 249574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis AttachToContextSucceedsBeforeUpdateTexImage) { 249674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 249774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 249874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 249974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU); 250074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 250174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 250274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attach to the secondary context. 250374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 250474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondEglContext)); 250574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID)); 250674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 250774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Verify that the texture object was created and bound. 250874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint texBinding = -1; 250974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding); 251074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EXPECT_EQ(SECOND_TEX_ID, texBinding); 251174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 251274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2513efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 251474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 251574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 251674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Try to use the texture from the secondary context. 251774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 251874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 251974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glViewport(0, 0, 1, 1); 252074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondTextureRenderer->drawTexture(); 252174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 252274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35)); 252374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 252474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 252574bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAbandoned) { 252674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 252774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 252874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2529efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 253074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 253174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 253274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 253374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 253474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 253574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to attach to the secondary context. 253674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mST->abandon(); 253774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 253874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to attach to the primary context. 253974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(NO_INIT, mST->attachToContext(SECOND_TEX_ID)); 254074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 254174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 254274bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAttached) { 254374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 254474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 254574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2546efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 254774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 254874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 254974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to attach to the primary context. 255074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID)); 255174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 255274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 255374bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, 255474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis AttachToContextFailsWhenAttachedBeforeUpdateTexImage) { 255574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 255674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 255774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to attach to the primary context. 255874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID)); 255974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 256074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 256174bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWithNoDisplay) { 256274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 256374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 256474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2565efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 256674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 256774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 256874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 256974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 257074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 257174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Make there be no current display. 257274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 257374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGL_NO_CONTEXT)); 257474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(EGL_SUCCESS, eglGetError()); 257574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 257674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attempt to attach with no context current. 257774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID)); 257874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 257974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 258074bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceedsTwice) { 258174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 258274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 258374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the primary context. 2584efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 258574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 258674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 258774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 258874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 258974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 259074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attach to the secondary context. 259174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 259274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondEglContext)); 259374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID)); 259474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 259574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the secondary context. 259674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 259774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 259874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attach to the tertiary context. 259974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 260074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mThirdEglContext)); 260174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID)); 260274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 260374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Verify that the texture object was created and bound. 260474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint texBinding = -1; 260574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding); 260674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EXPECT_EQ(THIRD_TEX_ID, texBinding); 260774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 260874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Try to use the texture from the tertiary context. 260974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 261074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 261174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glViewport(0, 0, 1, 1); 261274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mThirdTextureRenderer->drawTexture(); 261374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 261474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35)); 261574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 261674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 261774bed55fff0132be319bcd1703970516ae28b3a9Jamie GennisTEST_F(SurfaceTextureMultiContextGLTest, 261874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis AttachToContextSucceedsTwiceBeforeUpdateTexImage) { 261974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 262074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 262174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the primary context. 262274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 262374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 262474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attach to the secondary context. 262574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 262674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mSecondEglContext)); 262774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID)); 262874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 262974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Detach from the secondary context. 263074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->detachFromContext()); 263174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 263274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attach to the tertiary context. 263374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 263474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mThirdEglContext)); 263574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID)); 263674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 263774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Verify that the texture object was created and bound. 263874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint texBinding = -1; 263974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding); 264074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EXPECT_EQ(THIRD_TEX_ID, texBinding); 264174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 264274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Latch the texture contents on the tertiary context. 2643efc7ab6dcea8c22ddd7c0259ef4ab4bbf1e93044Jamie Gennis mFW->waitForFrame(); 264474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(OK, mST->updateTexImage()); 264574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 264674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Try to use the texture from the tertiary context. 264774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClearColor(0.2, 0.2, 0.2, 0.2); 264874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glClear(GL_COLOR_BUFFER_BIT); 264974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glViewport(0, 0, 1, 1); 265074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mThirdTextureRenderer->drawTexture(); 265174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 265274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ASSERT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35)); 2653ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis} 2654ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 265590ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse HallTEST_F(SurfaceTextureMultiContextGLTest, 265690ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall UpdateTexImageSucceedsForBufferConsumedBeforeDetach) { 265790ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true)); 265831a353da225af5329735451c761b430d82dfda1bJamie Gennis ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2)); 265990ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall 266090ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall // produce two frames and consume them both on the primary context 266190ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 266290ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall mFW->waitForFrame(); 266390ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_EQ(OK, mST->updateTexImage()); 266490ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall 266590ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 266690ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall mFW->waitForFrame(); 266790ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_EQ(OK, mST->updateTexImage()); 266890ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall 266990ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall // produce one more frame 267090ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW)); 267190ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall 267290ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall // Detach from the primary context and attach to the secondary context 267390ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_EQ(OK, mST->detachFromContext()); 267490ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 267590ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall mSecondEglContext)); 267690ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID)); 267790ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall 267890ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall // Consume final frame on secondary context 267990ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall mFW->waitForFrame(); 268090ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall ASSERT_EQ(OK, mST->updateTexImage()); 268190ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall} 268290ed8508ed89b4fdb5c21d621b29369d31dcb958Jesse Hall 26835451d15ee209f29d64beea87583f7058dee69911Jamie Gennis} // namespace android 2684