|  | // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // This file contains unit tests for gles2 commmands | 
|  |  | 
|  | #include <limits> | 
|  |  | 
|  | #include "base/bind.h" | 
|  | #include "base/synchronization/waitable_event.h" | 
|  | #include "base/threading/thread.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  | #include "gpu/command_buffer/common/gles2_cmd_format.h" | 
|  |  | 
|  | namespace gpu { | 
|  | namespace gles2 { | 
|  |  | 
|  | class GLES2FormatTest : public testing::Test { | 
|  | protected: | 
|  | static const unsigned char kInitialValue = 0xBD; | 
|  |  | 
|  | virtual void SetUp() { | 
|  | memset(buffer_, kInitialValue, sizeof(buffer_)); | 
|  | } | 
|  |  | 
|  | virtual void TearDown() { | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | T* GetBufferAs() { | 
|  | return static_cast<T*>(static_cast<void*>(&buffer_)); | 
|  | } | 
|  |  | 
|  | void CheckBytesWritten( | 
|  | const void* end, size_t expected_size, size_t written_size) { | 
|  | size_t actual_size = static_cast<const unsigned char*>(end) - | 
|  | GetBufferAs<const unsigned char>(); | 
|  | EXPECT_LT(actual_size, sizeof(buffer_)); | 
|  | EXPECT_GT(actual_size, 0u); | 
|  | EXPECT_EQ(expected_size, actual_size); | 
|  | EXPECT_EQ(kInitialValue, buffer_[written_size]); | 
|  | EXPECT_NE(kInitialValue, buffer_[written_size - 1]); | 
|  | } | 
|  |  | 
|  | void CheckBytesWrittenMatchesExpectedSize( | 
|  | const void* end, size_t expected_size) { | 
|  | CheckBytesWritten(end, expected_size, expected_size); | 
|  | } | 
|  |  | 
|  | private: | 
|  | unsigned char buffer_[1024]; | 
|  | }; | 
|  |  | 
|  | void SignalCompletion(uint32* assigned_async_token_ptr, | 
|  | uint32 async_token, | 
|  | AsyncUploadSync* sync) { | 
|  | EXPECT_EQ(async_token, *assigned_async_token_ptr); | 
|  | sync->SetAsyncUploadToken(async_token); | 
|  | } | 
|  |  | 
|  | TEST(GLES2FormatAsyncUploadSyncTest, AsyncUploadSync) { | 
|  | const size_t kSize = 10; | 
|  | const size_t kCount = 1000; | 
|  |  | 
|  | base::Thread thread("GLES2FormatUploadSyncTest - Fake Upload Thread"); | 
|  | thread.Start(); | 
|  |  | 
|  | // Run the same test 50 times so we retest the wrap as well. | 
|  | for (size_t test_run = 0; test_run < 50; ++test_run) { | 
|  | AsyncUploadSync sync; | 
|  | sync.Reset(); | 
|  |  | 
|  | uint32 buffer_tokens[kSize]; | 
|  | memset(buffer_tokens, 0, sizeof(buffer_tokens)); | 
|  |  | 
|  | // Start with a token large enough so that we'll wrap. | 
|  | uint32 async_token = std::numeric_limits<uint32>::max() - kCount / 2; | 
|  |  | 
|  | // Set initial async token. | 
|  | sync.SetAsyncUploadToken(async_token); | 
|  |  | 
|  | for (size_t i = 0; i < kCount; ++i) { | 
|  | size_t buffer = i % kSize; | 
|  |  | 
|  | // Loop until previous async token has passed if any was set. | 
|  | while (buffer_tokens[buffer] && | 
|  | !sync.HasAsyncUploadTokenPassed(buffer_tokens[buffer])) | 
|  | base::PlatformThread::YieldCurrentThread(); | 
|  |  | 
|  | // Next token, skip 0. | 
|  | async_token++; | 
|  | if (async_token == 0) | 
|  | async_token++; | 
|  |  | 
|  | // Set the buffer's associated token. | 
|  | buffer_tokens[buffer] = async_token; | 
|  |  | 
|  | // Set the async upload token on the fake upload thread and assert that | 
|  | // the associated buffer still has the given token. | 
|  | thread.message_loop()->PostTask(FROM_HERE, | 
|  | base::Bind(&SignalCompletion, | 
|  | &buffer_tokens[buffer], | 
|  | async_token, | 
|  | &sync)); | 
|  | } | 
|  |  | 
|  | // Flush the thread message loop before starting again. | 
|  | base::WaitableEvent waitable(false, false); | 
|  | thread.message_loop()->PostTask(FROM_HERE, | 
|  | base::Bind(&base::WaitableEvent::Signal, | 
|  | base::Unretained(&waitable))); | 
|  | waitable.Wait(); | 
|  | } | 
|  | } | 
|  |  | 
|  | // GCC requires these declarations, but MSVC requires they not be present | 
|  | #ifndef _MSC_VER | 
|  | const unsigned char GLES2FormatTest::kInitialValue; | 
|  | #endif | 
|  |  | 
|  | #include "gpu/command_buffer/common/gles2_cmd_format_test_autogen.h" | 
|  |  | 
|  | }  // namespace gles2 | 
|  | }  // namespace gpu | 
|  |  |