| /*------------------------------------------------------------------------- |
| * drawElements Quality Program EGL Module |
| * --------------------------------------- |
| * |
| * Copyright 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Test negative use case of KHR_partial_update |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "teglNegativePartialUpdateTests.hpp" |
| |
| #include "tcuTestLog.hpp" |
| #include "tcuSurface.hpp" |
| |
| #include "egluCallLogWrapper.hpp" |
| #include "egluConfigFilter.hpp" |
| #include "egluNativeWindow.hpp" |
| #include "egluStrUtil.hpp" |
| #include "egluUnique.hpp" |
| #include "egluUtil.hpp" |
| |
| #include "eglwLibrary.hpp" |
| #include "eglwEnums.hpp" |
| |
| using namespace eglu; |
| using namespace eglw; |
| using tcu::TestLog; |
| |
| namespace deqp |
| { |
| namespace egl |
| { |
| namespace |
| { |
| |
| class NegativePartialUpdateTest : public TestCase |
| { |
| public: |
| enum SurfaceType // used as a bit field when selecting a suitable EGL config |
| { |
| SURFACETYPE_WINDOW = 1 << 0, |
| SURFACETYPE_PBUFFER = 1 << 1 |
| }; |
| |
| NegativePartialUpdateTest(EglTestContext &eglTestCtx, bool preserveBuffer, SurfaceType surfaceType, |
| const char *name, const char *description); |
| ~NegativePartialUpdateTest(void); |
| void init(void); |
| void deinit(void); |
| virtual IterateResult iterate(void) = 0; |
| |
| protected: |
| void expectError(eglw::EGLenum error); |
| void expectBoolean(EGLBoolean expected, EGLBoolean got); |
| inline void expectTrue(eglw::EGLBoolean got) |
| { |
| expectBoolean(EGL_TRUE, got); |
| } |
| inline void expectFalse(eglw::EGLBoolean got) |
| { |
| expectBoolean(EGL_FALSE, got); |
| } |
| |
| const bool m_preserveBuffer; |
| SurfaceType m_surfaceType; |
| EGLDisplay m_eglDisplay; |
| EGLConfig m_eglConfig; |
| NativeWindow *m_window; |
| EGLSurface m_eglSurface; |
| EGLContext m_eglContext; |
| }; |
| |
| bool isWindow(const CandidateConfig &c) |
| { |
| return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT; |
| } |
| |
| bool isPbuffer(const CandidateConfig &c) |
| { |
| return (c.surfaceType() & EGL_PBUFFER_BIT) == EGL_PBUFFER_BIT; |
| } |
| |
| bool isES2Renderable(const CandidateConfig &c) |
| { |
| return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT; |
| } |
| |
| bool hasPreserveSwap(const CandidateConfig &c) |
| { |
| return (c.surfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == EGL_SWAP_BEHAVIOR_PRESERVED_BIT; |
| } |
| |
| EGLConfig getEGLConfig(const Library &egl, EGLDisplay eglDisplay, unsigned surfaceTypes, bool preserveBuffer) |
| { |
| FilterList filters; |
| if ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_WINDOW) != 0) |
| filters << isWindow; |
| if ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_PBUFFER) != 0) |
| filters << isPbuffer; |
| if (((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_WINDOW) == 0) && |
| ((surfaceTypes & NegativePartialUpdateTest::SURFACETYPE_PBUFFER) == 0)) |
| DE_FATAL("Invalid surfaceType"); |
| |
| filters << isES2Renderable; |
| |
| if (preserveBuffer) |
| filters << hasPreserveSwap; |
| |
| return chooseSingleConfig(egl, eglDisplay, filters); |
| } |
| |
| EGLContext initAndMakeCurrentEGLContext(const Library &egl, EGLDisplay eglDisplay, EGLSurface eglSurface, |
| EGLConfig eglConfig, const EGLint *attribList) |
| { |
| EGLContext eglContext = EGL_NO_CONTEXT; |
| |
| egl.bindAPI(EGL_OPENGL_ES_API); |
| eglContext = egl.createContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList); |
| EGLU_CHECK_MSG(egl, "eglCreateContext"); |
| TCU_CHECK(eglSurface != EGL_NO_SURFACE); |
| egl.makeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); |
| EGLU_CHECK_MSG(egl, "eglMakeCurrent"); |
| |
| return eglContext; |
| } |
| |
| NegativePartialUpdateTest::NegativePartialUpdateTest(EglTestContext &eglTestCtx, bool preserveBuffer, |
| SurfaceType surfaceType, const char *name, const char *description) |
| : TestCase(eglTestCtx, name, description) |
| , m_preserveBuffer(preserveBuffer) |
| , m_surfaceType(surfaceType) |
| , m_eglDisplay(EGL_NO_DISPLAY) |
| , m_window(nullptr) |
| , m_eglSurface(EGL_NO_SURFACE) |
| , m_eglContext(EGL_NO_CONTEXT) |
| { |
| } |
| |
| NegativePartialUpdateTest::~NegativePartialUpdateTest(void) |
| { |
| deinit(); |
| } |
| |
| void NegativePartialUpdateTest::init(void) |
| { |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| static const EGLint contextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; |
| const int width = 480; |
| const int height = 480; |
| |
| m_eglDisplay = getAndInitDisplay(m_eglTestCtx.getNativeDisplay()); |
| |
| if (!hasExtension(egl, m_eglDisplay, "EGL_KHR_partial_update")) |
| TCU_THROW(NotSupportedError, "EGL_KHR_partial_update is not supported"); |
| |
| if (m_surfaceType == SURFACETYPE_PBUFFER) |
| { |
| m_eglConfig = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, m_preserveBuffer); |
| const EGLint pbufferAttribList[] = {EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE}; |
| m_eglSurface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, pbufferAttribList); |
| } |
| else |
| { |
| m_eglConfig = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_WINDOW | SURFACETYPE_PBUFFER, m_preserveBuffer); |
| const NativeWindowFactory &factory = |
| selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); |
| m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, nullptr, |
| WindowParams(width, height, parseWindowVisibility(m_testCtx.getCommandLine()))); |
| m_eglSurface = |
| createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, nullptr); |
| } |
| m_eglContext = initAndMakeCurrentEGLContext(egl, m_eglDisplay, m_eglSurface, m_eglConfig, contextAttribList); |
| } |
| |
| void NegativePartialUpdateTest::deinit(void) |
| { |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| |
| if (m_eglContext != EGL_NO_CONTEXT) |
| { |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext)); |
| m_eglContext = EGL_NO_CONTEXT; |
| } |
| |
| if (m_eglSurface != EGL_NO_SURFACE) |
| { |
| EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface)); |
| m_eglSurface = EGL_NO_SURFACE; |
| } |
| |
| if (m_eglDisplay != EGL_NO_DISPLAY) |
| { |
| EGLU_CHECK_CALL(egl, terminate(m_eglDisplay)); |
| m_eglDisplay = EGL_NO_DISPLAY; |
| } |
| |
| delete m_window; |
| m_window = nullptr; |
| } |
| |
| void NegativePartialUpdateTest::expectError(EGLenum expected) |
| { |
| const EGLenum err = m_eglTestCtx.getLibrary().getError(); |
| |
| if (err != expected) |
| { |
| m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getErrorStr(expected) |
| << ", Got: " << eglu::getErrorStr(err) << TestLog::EndMessage; |
| if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid error"); |
| } |
| } |
| |
| void NegativePartialUpdateTest::expectBoolean(EGLBoolean expected, EGLBoolean got) |
| { |
| if (expected != got) |
| { |
| m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getBooleanStr(expected) |
| << ", Got: " << eglu::getBooleanStr(got) << TestLog::EndMessage; |
| if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value"); |
| } |
| } |
| |
| class NotPostableTest : public NegativePartialUpdateTest |
| { |
| public: |
| NotPostableTest(EglTestContext &context); |
| TestCase::IterateResult iterate(void); |
| }; |
| |
| NotPostableTest::NotPostableTest(EglTestContext &context) |
| : NegativePartialUpdateTest(context, false, SURFACETYPE_PBUFFER, "not_postable_surface", |
| "Call setDamageRegion() on pbuffer") |
| { |
| } |
| |
| TestCase::IterateResult NotPostableTest::iterate(void) |
| { |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| TestLog &log = m_testCtx.getLog(); |
| CallLogWrapper wrapper(egl, log); |
| EGLint damageRegion[] = {10, 10, 10, 10}; |
| int bufferAge = -1; |
| |
| wrapper.enableLogging(true); |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| { |
| tcu::ScopedLogSection(log, "Test1", "If the surface is pbuffer (not postable) --> EGL_BAD_MATCH"); |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); |
| EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge)); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, |
| DE_LENGTH_OF_ARRAY(damageRegion) / 4)); |
| expectError(EGL_BAD_MATCH); |
| } |
| |
| return STOP; |
| } |
| |
| class NotCurrentSurfaceTest : public NegativePartialUpdateTest |
| { |
| public: |
| NotCurrentSurfaceTest(EglTestContext &context); |
| TestCase::IterateResult iterate(void); |
| }; |
| |
| NotCurrentSurfaceTest::NotCurrentSurfaceTest(EglTestContext &context) |
| : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "not_current_surface", |
| "Call setDamageRegion() on pbuffer") |
| { |
| } |
| |
| TestCase::IterateResult NotCurrentSurfaceTest::iterate(void) |
| { |
| const int impossibleBufferAge = -26084; |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| const EGLint attribList[] = {EGL_WIDTH, 64, EGL_HEIGHT, 64, EGL_NONE}; |
| const eglu::UniqueSurface unusedPbuffer(egl, m_eglDisplay, |
| egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribList)); |
| TestLog &log = m_testCtx.getLog(); |
| CallLogWrapper wrapper(egl, log); |
| EGLint damageRegion[] = {10, 10, 10, 10}; |
| int bufferAge = impossibleBufferAge; |
| |
| wrapper.enableLogging(true); |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *unusedPbuffer, *unusedPbuffer, m_eglContext)); |
| { |
| tcu::ScopedLogSection( |
| log, "Test2.1", |
| "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE"); |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); |
| expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge)); |
| expectError(EGL_BAD_SURFACE); |
| |
| if (bufferAge != impossibleBufferAge) |
| { |
| log << tcu::TestLog::Message |
| << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " |
| << bufferAge << tcu::TestLog::EndMessage; |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed"); |
| } |
| } |
| { |
| tcu::ScopedLogSection( |
| log, "Test2.2", |
| "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH"); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1)); |
| expectError(EGL_BAD_MATCH); |
| } |
| |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| { |
| tcu::ScopedLogSection( |
| log, "Test3.1", |
| "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE"); |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); |
| expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge)); |
| expectError(EGL_BAD_SURFACE); |
| |
| if (bufferAge != impossibleBufferAge) |
| { |
| log << tcu::TestLog::Message |
| << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " |
| << bufferAge << tcu::TestLog::EndMessage; |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed"); |
| } |
| } |
| { |
| tcu::ScopedLogSection( |
| log, "Test3.2", |
| "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH"); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1)); |
| expectError(EGL_BAD_MATCH); |
| } |
| |
| if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context")) |
| { |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext)); |
| { |
| tcu::ScopedLogSection( |
| log, "Test4.1", |
| "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE"); |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); |
| expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge)); |
| expectError(EGL_BAD_SURFACE); |
| |
| if (bufferAge != impossibleBufferAge) |
| { |
| log << tcu::TestLog::Message |
| << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " |
| << bufferAge << tcu::TestLog::EndMessage; |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed"); |
| } |
| } |
| { |
| tcu::ScopedLogSection( |
| log, "Test4.2", |
| "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH"); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1)); |
| expectError(EGL_BAD_MATCH); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| class BufferPreservedTest : public NegativePartialUpdateTest |
| { |
| public: |
| BufferPreservedTest(EglTestContext &context); |
| TestCase::IterateResult iterate(void); |
| }; |
| |
| BufferPreservedTest::BufferPreservedTest(EglTestContext &context) |
| : NegativePartialUpdateTest(context, true, SURFACETYPE_WINDOW, "buffer_preserved", |
| "Call setDamageRegion() on pbuffer") |
| { |
| } |
| |
| TestCase::IterateResult BufferPreservedTest::iterate(void) |
| { |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| TestLog &log = m_testCtx.getLog(); |
| CallLogWrapper wrapper(egl, log); |
| EGLint damageRegion[] = {10, 10, 10, 10}; |
| int bufferAge = -1; |
| |
| wrapper.enableLogging(true); |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| { |
| tcu::ScopedLogSection(log, "Test3", "If buffer_preserved --> EGL_BAD_MATCH"); |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)); |
| EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge)); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, |
| DE_LENGTH_OF_ARRAY(damageRegion) / 4)); |
| expectError(EGL_BAD_MATCH); |
| } |
| |
| return STOP; |
| } |
| |
| class SetTwiceTest : public NegativePartialUpdateTest |
| { |
| public: |
| SetTwiceTest(EglTestContext &context); |
| TestCase::IterateResult iterate(void); |
| }; |
| |
| SetTwiceTest::SetTwiceTest(EglTestContext &context) |
| : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "set_damage_region_twice", |
| "Call setDamageRegion() twice") |
| { |
| } |
| |
| TestCase::IterateResult SetTwiceTest::iterate(void) |
| { |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| TestLog &log = m_testCtx.getLog(); |
| CallLogWrapper wrapper(egl, log); |
| EGLint damageRegion[] = {10, 10, 10, 10}; |
| int bufferAge = -1; |
| |
| wrapper.enableLogging(true); |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| { |
| tcu::ScopedLogSection(log, "Test4", "If call setDamageRegion() twice --> EGL_BAD_ACCESS"); |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); |
| EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge)); |
| expectTrue(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, |
| DE_LENGTH_OF_ARRAY(damageRegion) / 4)); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, |
| DE_LENGTH_OF_ARRAY(damageRegion) / 4)); |
| expectError(EGL_BAD_ACCESS); |
| } |
| |
| return STOP; |
| } |
| |
| class NoAgeTest : public NegativePartialUpdateTest |
| { |
| public: |
| NoAgeTest(EglTestContext &context); |
| TestCase::IterateResult iterate(void); |
| }; |
| |
| NoAgeTest::NoAgeTest(EglTestContext &context) |
| : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "set_damage_region_before_query_age", |
| "Call setDamageRegion() without querying buffer age") |
| { |
| } |
| |
| TestCase::IterateResult NoAgeTest::iterate(void) |
| { |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| TestLog &log = m_testCtx.getLog(); |
| CallLogWrapper wrapper(egl, log); |
| EGLint damageRegion[] = {10, 10, 10, 10}; |
| |
| wrapper.enableLogging(true); |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| { |
| tcu::ScopedLogSection(log, "Test5", "If buffer age is not queried --> EGL_BAD_ACCESS"); |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, |
| DE_LENGTH_OF_ARRAY(damageRegion) / 4)); |
| expectError(EGL_BAD_ACCESS); |
| } |
| |
| return STOP; |
| } |
| |
| class PassNullTest : public NegativePartialUpdateTest |
| { |
| public: |
| PassNullTest(EglTestContext &context); |
| TestCase::IterateResult iterate(void); |
| }; |
| |
| PassNullTest::PassNullTest(EglTestContext &context) |
| : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "pass_null_0_as_params", |
| "Call setDamageRegion() with (NULL, 0)") |
| { |
| } |
| |
| TestCase::IterateResult PassNullTest::iterate(void) |
| { |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| TestLog &log = m_testCtx.getLog(); |
| CallLogWrapper wrapper(egl, log); |
| int bufferAge = -1; |
| |
| wrapper.enableLogging(true); |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| { |
| tcu::ScopedLogSection(log, "Test6", "If pass (null, 0) to setDamageRegion(), no error"); |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); |
| EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge)); |
| expectTrue(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, nullptr, 0)); |
| expectError(EGL_SUCCESS); |
| } |
| |
| return STOP; |
| } |
| |
| class NotCurrentSurfaceTest2 : public NegativePartialUpdateTest |
| { |
| public: |
| NotCurrentSurfaceTest2(EglTestContext &context); |
| TestCase::IterateResult iterate(void); |
| }; |
| |
| NotCurrentSurfaceTest2::NotCurrentSurfaceTest2(EglTestContext &context) |
| : NegativePartialUpdateTest(context, false, SURFACETYPE_WINDOW, "not_current_surface2", |
| "Call setDamageRegion() on pbuffer") |
| { |
| } |
| |
| TestCase::IterateResult NotCurrentSurfaceTest2::iterate(void) |
| { |
| const Library &egl = m_eglTestCtx.getLibrary(); |
| const EGLint attribList[] = {EGL_WIDTH, 64, EGL_HEIGHT, 64, EGL_NONE}; |
| const eglu::UniqueSurface unusedPbuffer(egl, m_eglDisplay, |
| egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribList)); |
| TestLog &log = m_testCtx.getLog(); |
| CallLogWrapper wrapper(egl, log); |
| EGLint damageRegion[] = {10, 10, 10, 10}; |
| int bufferAge = -1; |
| |
| wrapper.enableLogging(true); |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| |
| EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); |
| EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge)); |
| |
| { |
| tcu::ScopedLogSection( |
| log, "Test7", |
| "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH"); |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *unusedPbuffer, *unusedPbuffer, m_eglContext)); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1)); |
| expectError(EGL_BAD_MATCH); |
| } |
| { |
| tcu::ScopedLogSection( |
| log, "Test8", |
| "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH"); |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1)); |
| expectError(EGL_BAD_MATCH); |
| } |
| if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context")) |
| { |
| tcu::ScopedLogSection( |
| log, "Test9", |
| "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH"); |
| EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext)); |
| expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1)); |
| expectError(EGL_BAD_MATCH); |
| } |
| |
| return STOP; |
| } |
| |
| } // namespace |
| |
| NegativePartialUpdateTests::NegativePartialUpdateTests(EglTestContext &eglTestCtx) |
| : TestCaseGroup(eglTestCtx, "negative_partial_update", "Negative partial update tests") |
| { |
| } |
| |
| void NegativePartialUpdateTests::init(void) |
| { |
| addChild(new NotPostableTest(m_eglTestCtx)); |
| addChild(new NotCurrentSurfaceTest(m_eglTestCtx)); |
| addChild(new BufferPreservedTest(m_eglTestCtx)); |
| addChild(new SetTwiceTest(m_eglTestCtx)); |
| addChild(new NoAgeTest(m_eglTestCtx)); |
| addChild(new PassNullTest(m_eglTestCtx)); |
| addChild(new NotCurrentSurfaceTest2(m_eglTestCtx)); |
| } |
| |
| } // namespace egl |
| } // namespace deqp |