| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/common/gpu/client/gpu_memory_buffer_impl.h" |
| 6 |
| 7 #if defined(OS_ANDROID) |
| 8 #include <android/native_window_jni.h> |
| 9 #include <map> |
| 10 #endif |
| 11 |
| 12 #include "base/bind.h" |
| 13 #include "content/common/gpu/client/gpu_memory_buffer_factory_host.h" |
| 14 #include "content/common/gpu/gpu_memory_buffer_factory.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 |
| 17 #if defined(OS_ANDROID) |
| 18 #include "base/android/jni_android.h" |
| 19 #include "base/memory/linked_ptr.h" |
| 20 #include "content/common/android/surface_texture_manager.h" |
| 21 #include "ui/gl/android/scoped_java_surface.h" |
| 22 #include "ui/gl/android/surface_texture.h" |
| 23 #endif |
| 24 |
| 25 namespace content { |
| 26 namespace { |
| 27 |
| 28 #if defined(OS_ANDROID) |
| 29 class SurfaceTextureManagerImpl : public SurfaceTextureManager { |
| 30 public: |
| 31 // Overridden from SurfaceTextureManager: |
| 32 void RegisterSurfaceTexture(int surface_texture_id, |
| 33 int client_id, |
| 34 gfx::SurfaceTexture* surface_texture) override { |
| 35 surfaces_[surface_texture_id] = make_linked_ptr( |
| 36 new gfx::ScopedJavaSurface(surface_texture)); |
| 37 } |
| 38 void UnregisterSurfaceTexture(int surface_texture_id, |
| 39 int client_id) override { |
| 40 surfaces_.erase(surface_texture_id); |
| 41 } |
| 42 gfx::AcceleratedWidget AcquireNativeWidgetForSurfaceTexture( |
| 43 int surface_texture_id) override { |
| 44 JNIEnv* env = base::android::AttachCurrentThread(); |
| 45 return ANativeWindow_fromSurface( |
| 46 env, surfaces_[surface_texture_id]->j_surface().obj()); |
| 47 } |
| 48 |
| 49 private: |
| 50 typedef std::map<int, linked_ptr<gfx::ScopedJavaSurface>> SurfaceMap; |
| 51 SurfaceMap surfaces_; |
| 52 }; |
| 53 #endif |
| 54 |
| 55 class GpuMemoryBufferImplTest |
| 56 : public testing::TestWithParam<gfx::GpuMemoryBufferType>, |
| 57 public GpuMemoryBufferFactoryHost { |
| 58 public: |
| 59 GpuMemoryBufferImplTest() : factory_(GpuMemoryBufferFactory::Create()) { |
| 60 #if defined(OS_ANDROID) |
| 61 SurfaceTextureManager::InitInstance(&surface_texture_manager_); |
| 62 #endif |
| 63 } |
| 64 ~GpuMemoryBufferImplTest() override { |
| 65 #if defined(OS_ANDROID) |
| 66 SurfaceTextureManager::InitInstance(NULL); |
| 67 #endif |
| 68 } |
| 69 |
| 70 // Overridden from GpuMemoryBufferFactoryHost: |
| 71 void CreateGpuMemoryBuffer( |
| 72 gfx::GpuMemoryBufferType type, |
| 73 gfx::GpuMemoryBufferId id, |
| 74 const gfx::Size& size, |
| 75 gfx::GpuMemoryBuffer::Format format, |
| 76 gfx::GpuMemoryBuffer::Usage usage, |
| 77 int client_id, |
| 78 const CreateGpuMemoryBufferCallback& callback) override { |
| 79 callback.Run(factory_->CreateGpuMemoryBuffer(type, |
| 80 id, |
| 81 size, |
| 82 format, |
| 83 usage, |
| 84 client_id)); |
| 85 } |
| 86 void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferType type, |
| 87 gfx::GpuMemoryBufferId id, |
| 88 int client_id, |
| 89 int32 sync_point) override { |
| 90 factory_->DestroyGpuMemoryBuffer(type, id, client_id); |
| 91 } |
| 92 |
| 93 private: |
| 94 scoped_ptr<GpuMemoryBufferFactory> factory_; |
| 95 #if defined(OS_ANDROID) |
| 96 SurfaceTextureManagerImpl surface_texture_manager_; |
| 97 #endif |
| 98 }; |
| 99 |
| 100 struct CreateRequest { |
| 101 scoped_ptr<GpuMemoryBufferImpl> result; |
| 102 }; |
| 103 |
| 104 void GpuMemoryBufferCreated(CreateRequest* request, |
| 105 scoped_ptr<GpuMemoryBufferImpl> buffer) { |
| 106 request->result = buffer.Pass(); |
| 107 } |
| 108 |
| 109 TEST_P(GpuMemoryBufferImplTest, Create) { |
| 110 const int kBufferId = 1; |
| 111 const int kClientId = 0; |
| 112 |
| 113 gfx::Size buffer_size(1, 1); |
| 114 |
| 115 const gfx::GpuMemoryBuffer::Format formats[] = { |
| 116 gfx::GpuMemoryBuffer::RGBA_8888, |
| 117 gfx::GpuMemoryBuffer::RGBX_8888, |
| 118 gfx::GpuMemoryBuffer::BGRA_8888 |
| 119 }; |
| 120 for (gfx::GpuMemoryBuffer::Format format : formats) { |
| 121 const gfx::GpuMemoryBuffer::Usage usages[] = { |
| 122 gfx::GpuMemoryBuffer::MAP, |
| 123 gfx::GpuMemoryBuffer::SCANOUT |
| 124 }; |
| 125 for (gfx::GpuMemoryBuffer::Usage usage : usages) { |
| 126 if (!GpuMemoryBufferImpl::IsConfigurationSupported( |
| 127 GetParam(), format, usage)) |
| 128 continue; |
| 129 |
| 130 CreateRequest request; |
| 131 GpuMemoryBufferImpl::Create(GetParam(), |
| 132 kBufferId, |
| 133 buffer_size, |
| 134 format, |
| 135 usage, |
| 136 kClientId, |
| 137 base::Bind(GpuMemoryBufferCreated, &request)); |
| 138 |
| 139 ASSERT_TRUE(request.result); |
| 140 |
| 141 scoped_ptr<GpuMemoryBufferImpl> buffer = request.result.Pass(); |
| 142 EXPECT_EQ(buffer->GetFormat(), format); |
| 143 } |
| 144 } |
| 145 } |
| 146 |
| 147 struct AllocateRequest { |
| 148 gfx::GpuMemoryBufferHandle result; |
| 149 }; |
| 150 |
| 151 void GpuMemoryBufferAllocated(AllocateRequest* request, |
| 152 const gfx::GpuMemoryBufferHandle& handle) { |
| 153 request->result = handle; |
| 154 } |
| 155 |
| 156 void DeletedGpuMemoryBuffer(gfx::GpuMemoryBufferType type, |
| 157 gfx::GpuMemoryBufferId id, |
| 158 int child_client_id, |
| 159 uint32 sync_point) { |
| 160 GpuMemoryBufferImpl::DeletedByChildProcess(type, |
| 161 id, |
| 162 base::GetCurrentProcessHandle(), |
| 163 child_client_id, |
| 164 sync_point); |
| 165 } |
| 166 |
| 167 TEST_P(GpuMemoryBufferImplTest, AllocateForChildProcess) { |
| 168 const int kBufferId = 1; |
| 169 const int kChildClientId = 1; |
| 170 |
| 171 gfx::Size buffer_size(1, 1); |
| 172 |
| 173 const gfx::GpuMemoryBuffer::Format formats[] = { |
| 174 gfx::GpuMemoryBuffer::RGBA_8888, |
| 175 gfx::GpuMemoryBuffer::RGBX_8888, |
| 176 gfx::GpuMemoryBuffer::BGRA_8888 |
| 177 }; |
| 178 for (gfx::GpuMemoryBuffer::Format format : formats) { |
| 179 const gfx::GpuMemoryBuffer::Usage usages[] = { |
| 180 gfx::GpuMemoryBuffer::MAP, |
| 181 gfx::GpuMemoryBuffer::SCANOUT |
| 182 }; |
| 183 for (gfx::GpuMemoryBuffer::Usage usage : usages) { |
| 184 if (!GpuMemoryBufferImpl::IsConfigurationSupported( |
| 185 GetParam(), format, usage)) |
| 186 continue; |
| 187 |
| 188 AllocateRequest request; |
| 189 GpuMemoryBufferImpl::AllocateForChildProcess( |
| 190 GetParam(), |
| 191 kBufferId, |
| 192 buffer_size, |
| 193 format, |
| 194 usage, |
| 195 base::GetCurrentProcessHandle(), |
| 196 kChildClientId, |
| 197 base::Bind(GpuMemoryBufferAllocated, &request)); |
| 198 |
| 199 EXPECT_EQ(request.result.type, GetParam()); |
| 200 |
| 201 scoped_ptr<GpuMemoryBufferImpl> buffer( |
| 202 GpuMemoryBufferImpl::CreateFromHandle( |
| 203 request.result, |
| 204 buffer_size, |
| 205 format, |
| 206 base::Bind(DeletedGpuMemoryBuffer, |
| 207 GetParam(), |
| 208 kBufferId, |
| 209 kChildClientId))); |
| 210 ASSERT_TRUE(buffer); |
| 211 EXPECT_EQ(buffer->GetFormat(), format); |
| 212 } |
| 213 } |
| 214 } |
| 215 |
| 216 TEST_P(GpuMemoryBufferImplTest, Map) { |
| 217 const int kBufferId = 1; |
| 218 const int kChildClientId = 1; |
| 219 |
| 220 gfx::Size buffer_size(1, 1); |
| 221 |
| 222 const gfx::GpuMemoryBuffer::Format formats[] = { |
| 223 gfx::GpuMemoryBuffer::RGBA_8888, |
| 224 gfx::GpuMemoryBuffer::RGBX_8888, |
| 225 gfx::GpuMemoryBuffer::BGRA_8888 |
| 226 }; |
| 227 for (gfx::GpuMemoryBuffer::Format format : formats) { |
| 228 if (!GpuMemoryBufferImpl::IsConfigurationSupported( |
| 229 GetParam(), format, gfx::GpuMemoryBuffer::MAP)) |
| 230 continue; |
| 231 |
| 232 size_t width_in_bytes = |
| 233 GpuMemoryBufferImpl::BytesPerPixel(format) * buffer_size.width(); |
| 234 EXPECT_GT(width_in_bytes, 0u); |
| 235 scoped_ptr<char[]> data(new char[width_in_bytes]); |
| 236 memset(data.get(), 0x2a, width_in_bytes); |
| 237 |
| 238 AllocateRequest request; |
| 239 GpuMemoryBufferImpl::AllocateForChildProcess( |
| 240 GetParam(), |
| 241 kBufferId, |
| 242 buffer_size, |
| 243 format, |
| 244 gfx::GpuMemoryBuffer::MAP, |
| 245 base::GetCurrentProcessHandle(), |
| 246 kChildClientId, |
| 247 base::Bind(GpuMemoryBufferAllocated, &request)); |
| 248 |
| 249 EXPECT_EQ(request.result.type, GetParam()); |
| 250 |
| 251 scoped_ptr<GpuMemoryBufferImpl> buffer( |
| 252 GpuMemoryBufferImpl::CreateFromHandle( |
| 253 request.result, |
| 254 buffer_size, |
| 255 format, |
| 256 base::Bind(DeletedGpuMemoryBuffer, |
| 257 GetParam(), |
| 258 kBufferId, |
| 259 kChildClientId))); |
| 260 ASSERT_TRUE(buffer); |
| 261 EXPECT_FALSE(buffer->IsMapped()); |
| 262 |
| 263 void* memory = buffer->Map(); |
| 264 ASSERT_TRUE(memory); |
| 265 EXPECT_TRUE(buffer->IsMapped()); |
| 266 uint32 stride = buffer->GetStride(); |
| 267 EXPECT_GE(stride, width_in_bytes); |
| 268 memcpy(memory, data.get(), width_in_bytes); |
| 269 EXPECT_EQ(memcmp(memory, data.get(), width_in_bytes), 0); |
| 270 buffer->Unmap(); |
| 271 EXPECT_FALSE(buffer->IsMapped()); |
| 272 } |
| 273 } |
| 274 |
| 275 std::vector<gfx::GpuMemoryBufferType> GetSupportedGpuMemoryBufferTypes() { |
| 276 std::vector<gfx::GpuMemoryBufferType> supported_types; |
| 277 GpuMemoryBufferImpl::GetSupportedTypes(&supported_types); |
| 278 return supported_types; |
| 279 } |
| 280 |
| 281 INSTANTIATE_TEST_CASE_P( |
| 282 GpuMemoryBufferImplTests, |
| 283 GpuMemoryBufferImplTest, |
| 284 ::testing::ValuesIn(GetSupportedGpuMemoryBufferTypes())); |
| 285 |
| 286 } // namespace |
| 287 } // namespace content |
| OLD | NEW |