Index: content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc |
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc b/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..84740cf7764e86d2107e3ec6ec166dd105e02043 |
--- /dev/null |
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_unittest.cc |
@@ -0,0 +1,287 @@ |
+// Copyright 2014 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. |
+ |
+#include "content/common/gpu/client/gpu_memory_buffer_impl.h" |
+ |
+#if defined(OS_ANDROID) |
+#include <android/native_window_jni.h> |
+#include <map> |
+#endif |
+ |
+#include "base/bind.h" |
+#include "content/common/gpu/client/gpu_memory_buffer_factory_host.h" |
+#include "content/common/gpu/gpu_memory_buffer_factory.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+#if defined(OS_ANDROID) |
+#include "base/android/jni_android.h" |
+#include "base/memory/linked_ptr.h" |
+#include "content/common/android/surface_texture_manager.h" |
+#include "ui/gl/android/scoped_java_surface.h" |
+#include "ui/gl/android/surface_texture.h" |
+#endif |
+ |
+namespace content { |
+namespace { |
+ |
+#if defined(OS_ANDROID) |
+class SurfaceTextureManagerImpl : public SurfaceTextureManager { |
+ public: |
+ // Overridden from SurfaceTextureManager: |
+ void RegisterSurfaceTexture(int surface_texture_id, |
+ int client_id, |
+ gfx::SurfaceTexture* surface_texture) override { |
+ surfaces_[surface_texture_id] = make_linked_ptr( |
+ new gfx::ScopedJavaSurface(surface_texture)); |
+ } |
+ void UnregisterSurfaceTexture(int surface_texture_id, |
+ int client_id) override { |
+ surfaces_.erase(surface_texture_id); |
+ } |
+ gfx::AcceleratedWidget AcquireNativeWidgetForSurfaceTexture( |
+ int surface_texture_id) override { |
+ JNIEnv* env = base::android::AttachCurrentThread(); |
+ return ANativeWindow_fromSurface( |
+ env, surfaces_[surface_texture_id]->j_surface().obj()); |
+ } |
+ |
+ private: |
+ typedef std::map<int, linked_ptr<gfx::ScopedJavaSurface>> SurfaceMap; |
+ SurfaceMap surfaces_; |
+}; |
+#endif |
+ |
+class GpuMemoryBufferImplTest |
+ : public testing::TestWithParam<gfx::GpuMemoryBufferType>, |
+ public GpuMemoryBufferFactoryHost { |
+ public: |
+ GpuMemoryBufferImplTest() : factory_(GpuMemoryBufferFactory::Create()) { |
+#if defined(OS_ANDROID) |
+ SurfaceTextureManager::InitInstance(&surface_texture_manager_); |
+#endif |
+ } |
+ ~GpuMemoryBufferImplTest() override { |
+#if defined(OS_ANDROID) |
+ SurfaceTextureManager::InitInstance(NULL); |
+#endif |
+ } |
+ |
+ // Overridden from GpuMemoryBufferFactoryHost: |
+ void CreateGpuMemoryBuffer( |
+ gfx::GpuMemoryBufferType type, |
+ gfx::GpuMemoryBufferId id, |
+ const gfx::Size& size, |
+ gfx::GpuMemoryBuffer::Format format, |
+ gfx::GpuMemoryBuffer::Usage usage, |
+ int client_id, |
+ const CreateGpuMemoryBufferCallback& callback) override { |
+ callback.Run(factory_->CreateGpuMemoryBuffer(type, |
+ id, |
+ size, |
+ format, |
+ usage, |
+ client_id)); |
+ } |
+ void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferType type, |
+ gfx::GpuMemoryBufferId id, |
+ int client_id, |
+ int32 sync_point) override { |
+ factory_->DestroyGpuMemoryBuffer(type, id, client_id); |
+ } |
+ |
+ private: |
+ scoped_ptr<GpuMemoryBufferFactory> factory_; |
+#if defined(OS_ANDROID) |
+ SurfaceTextureManagerImpl surface_texture_manager_; |
+#endif |
+}; |
+ |
+struct CreateRequest { |
+ scoped_ptr<GpuMemoryBufferImpl> result; |
+}; |
+ |
+void GpuMemoryBufferCreated(CreateRequest* request, |
+ scoped_ptr<GpuMemoryBufferImpl> buffer) { |
+ request->result = buffer.Pass(); |
+} |
+ |
+TEST_P(GpuMemoryBufferImplTest, Create) { |
+ const int kBufferId = 1; |
+ const int kClientId = 0; |
+ |
+ gfx::Size buffer_size(1, 1); |
+ |
+ const gfx::GpuMemoryBuffer::Format formats[] = { |
+ gfx::GpuMemoryBuffer::RGBA_8888, |
+ gfx::GpuMemoryBuffer::RGBX_8888, |
+ gfx::GpuMemoryBuffer::BGRA_8888 |
+ }; |
+ for (gfx::GpuMemoryBuffer::Format format : formats) { |
+ const gfx::GpuMemoryBuffer::Usage usages[] = { |
+ gfx::GpuMemoryBuffer::MAP, |
+ gfx::GpuMemoryBuffer::SCANOUT |
+ }; |
+ for (gfx::GpuMemoryBuffer::Usage usage : usages) { |
+ if (!GpuMemoryBufferImpl::IsConfigurationSupported( |
+ GetParam(), format, usage)) |
+ continue; |
+ |
+ CreateRequest request; |
+ GpuMemoryBufferImpl::Create(GetParam(), |
+ kBufferId, |
+ buffer_size, |
+ format, |
+ usage, |
+ kClientId, |
+ base::Bind(GpuMemoryBufferCreated, &request)); |
+ |
+ ASSERT_TRUE(request.result); |
+ |
+ scoped_ptr<GpuMemoryBufferImpl> buffer = request.result.Pass(); |
+ EXPECT_EQ(buffer->GetFormat(), format); |
+ } |
+ } |
+} |
+ |
+struct AllocateRequest { |
+ gfx::GpuMemoryBufferHandle result; |
+}; |
+ |
+void GpuMemoryBufferAllocated(AllocateRequest* request, |
+ const gfx::GpuMemoryBufferHandle& handle) { |
+ request->result = handle; |
+} |
+ |
+void DeletedGpuMemoryBuffer(gfx::GpuMemoryBufferType type, |
+ gfx::GpuMemoryBufferId id, |
+ int child_client_id, |
+ uint32 sync_point) { |
+ GpuMemoryBufferImpl::DeletedByChildProcess(type, |
+ id, |
+ base::GetCurrentProcessHandle(), |
+ child_client_id, |
+ sync_point); |
+} |
+ |
+TEST_P(GpuMemoryBufferImplTest, AllocateForChildProcess) { |
+ const int kBufferId = 1; |
+ const int kChildClientId = 1; |
+ |
+ gfx::Size buffer_size(1, 1); |
+ |
+ const gfx::GpuMemoryBuffer::Format formats[] = { |
+ gfx::GpuMemoryBuffer::RGBA_8888, |
+ gfx::GpuMemoryBuffer::RGBX_8888, |
+ gfx::GpuMemoryBuffer::BGRA_8888 |
+ }; |
+ for (gfx::GpuMemoryBuffer::Format format : formats) { |
+ const gfx::GpuMemoryBuffer::Usage usages[] = { |
+ gfx::GpuMemoryBuffer::MAP, |
+ gfx::GpuMemoryBuffer::SCANOUT |
+ }; |
+ for (gfx::GpuMemoryBuffer::Usage usage : usages) { |
+ if (!GpuMemoryBufferImpl::IsConfigurationSupported( |
+ GetParam(), format, usage)) |
+ continue; |
+ |
+ AllocateRequest request; |
+ GpuMemoryBufferImpl::AllocateForChildProcess( |
+ GetParam(), |
+ kBufferId, |
+ buffer_size, |
+ format, |
+ usage, |
+ base::GetCurrentProcessHandle(), |
+ kChildClientId, |
+ base::Bind(GpuMemoryBufferAllocated, &request)); |
+ |
+ EXPECT_EQ(request.result.type, GetParam()); |
+ |
+ scoped_ptr<GpuMemoryBufferImpl> buffer( |
+ GpuMemoryBufferImpl::CreateFromHandle( |
+ request.result, |
+ buffer_size, |
+ format, |
+ base::Bind(DeletedGpuMemoryBuffer, |
+ GetParam(), |
+ kBufferId, |
+ kChildClientId))); |
+ ASSERT_TRUE(buffer); |
+ EXPECT_EQ(buffer->GetFormat(), format); |
+ } |
+ } |
+} |
+ |
+TEST_P(GpuMemoryBufferImplTest, Map) { |
+ const int kBufferId = 1; |
+ const int kChildClientId = 1; |
+ |
+ gfx::Size buffer_size(1, 1); |
+ |
+ const gfx::GpuMemoryBuffer::Format formats[] = { |
+ gfx::GpuMemoryBuffer::RGBA_8888, |
+ gfx::GpuMemoryBuffer::RGBX_8888, |
+ gfx::GpuMemoryBuffer::BGRA_8888 |
+ }; |
+ for (gfx::GpuMemoryBuffer::Format format : formats) { |
+ if (!GpuMemoryBufferImpl::IsConfigurationSupported( |
+ GetParam(), format, gfx::GpuMemoryBuffer::MAP)) |
+ continue; |
+ |
+ size_t width_in_bytes = |
+ GpuMemoryBufferImpl::BytesPerPixel(format) * buffer_size.width(); |
+ EXPECT_GT(width_in_bytes, 0u); |
+ scoped_ptr<char[]> data(new char[width_in_bytes]); |
+ memset(data.get(), 0x2a, width_in_bytes); |
+ |
+ AllocateRequest request; |
+ GpuMemoryBufferImpl::AllocateForChildProcess( |
+ GetParam(), |
+ kBufferId, |
+ buffer_size, |
+ format, |
+ gfx::GpuMemoryBuffer::MAP, |
+ base::GetCurrentProcessHandle(), |
+ kChildClientId, |
+ base::Bind(GpuMemoryBufferAllocated, &request)); |
+ |
+ EXPECT_EQ(request.result.type, GetParam()); |
+ |
+ scoped_ptr<GpuMemoryBufferImpl> buffer( |
+ GpuMemoryBufferImpl::CreateFromHandle( |
+ request.result, |
+ buffer_size, |
+ format, |
+ base::Bind(DeletedGpuMemoryBuffer, |
+ GetParam(), |
+ kBufferId, |
+ kChildClientId))); |
+ ASSERT_TRUE(buffer); |
+ EXPECT_FALSE(buffer->IsMapped()); |
+ |
+ void* memory = buffer->Map(); |
+ ASSERT_TRUE(memory); |
+ EXPECT_TRUE(buffer->IsMapped()); |
+ uint32 stride = buffer->GetStride(); |
+ EXPECT_GE(stride, width_in_bytes); |
+ memcpy(memory, data.get(), width_in_bytes); |
+ EXPECT_EQ(memcmp(memory, data.get(), width_in_bytes), 0); |
+ buffer->Unmap(); |
+ EXPECT_FALSE(buffer->IsMapped()); |
+ } |
+} |
+ |
+std::vector<gfx::GpuMemoryBufferType> GetSupportedGpuMemoryBufferTypes() { |
+ std::vector<gfx::GpuMemoryBufferType> supported_types; |
+ GpuMemoryBufferImpl::GetSupportedTypes(&supported_types); |
+ return supported_types; |
+} |
+ |
+INSTANTIATE_TEST_CASE_P( |
+ GpuMemoryBufferImplTests, |
+ GpuMemoryBufferImplTest, |
+ ::testing::ValuesIn(GetSupportedGpuMemoryBufferTypes())); |
+ |
+} // namespace |
+} // namespace content |