| 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 |