Home | History | Annotate | Download | only in tests
      1 // Copyright (c) 2013 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 <GLES2/gl2.h>
      6 #include <GLES2/gl2chromium.h>
      7 #include <GLES2/gl2ext.h>
      8 #include <GLES2/gl2extchromium.h>
      9 
     10 #include "base/bind.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/process/process_handle.h"
     13 #include "gpu/command_buffer/client/gles2_implementation.h"
     14 #include "gpu/command_buffer/client/gpu_memory_buffer_factory.h"
     15 #include "gpu/command_buffer/service/command_buffer_service.h"
     16 #include "gpu/command_buffer/service/image_manager.h"
     17 #include "gpu/command_buffer/tests/gl_manager.h"
     18 #include "gpu/command_buffer/tests/gl_test_utils.h"
     19 #include "testing/gmock/include/gmock/gmock.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "ui/gl/gl_image.h"
     22 
     23 using testing::_;
     24 using testing::IgnoreResult;
     25 using testing::InvokeWithoutArgs;
     26 using testing::Invoke;
     27 using testing::Return;
     28 using testing::SetArgPointee;
     29 using testing::StrictMock;
     30 
     31 namespace gpu {
     32 namespace gles2 {
     33 
     34 static const int kImageWidth = 32;
     35 static const int kImageHeight = 32;
     36 static const int kImageBytesPerPixel = 4;
     37 
     38 class MockGpuMemoryBuffer : public gfx::GpuMemoryBuffer {
     39  public:
     40   MockGpuMemoryBuffer(int width, int height) {}
     41   virtual ~MockGpuMemoryBuffer() {
     42     Die();
     43   }
     44 
     45   MOCK_METHOD2(Map, void(gfx::GpuMemoryBuffer::AccessMode, void**));
     46   MOCK_METHOD0(Unmap, void());
     47   MOCK_CONST_METHOD0(IsMapped, bool());
     48   MOCK_CONST_METHOD0(GetStride, uint32());
     49   MOCK_CONST_METHOD0(GetHandle, gfx::GpuMemoryBufferHandle());
     50   MOCK_METHOD0(Die, void());
     51 
     52  private:
     53   DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBuffer);
     54 };
     55 
     56 class MockGpuMemoryBufferFactory : public GpuMemoryBufferFactory {
     57  public:
     58   MockGpuMemoryBufferFactory() {}
     59   virtual ~MockGpuMemoryBufferFactory() {}
     60 
     61   MOCK_METHOD3(CreateGpuMemoryBuffer,
     62                gfx::GpuMemoryBuffer*(size_t, size_t, unsigned));
     63 
     64  private:
     65   DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBufferFactory);
     66 };
     67 
     68 class MockGpuMemoryBufferTest : public testing::Test {
     69  protected:
     70   virtual void SetUp() {
     71     GLManager::Options options;
     72     image_manager_ = new ImageManager;
     73     gpu_memory_buffer_factory_.reset(new MockGpuMemoryBufferFactory);
     74     options.image_manager = image_manager_.get();
     75     options.gpu_memory_buffer_factory = gpu_memory_buffer_factory_.get();
     76 
     77     gl_.Initialize(options);
     78     gl_.MakeCurrent();
     79 
     80     glGenTextures(2, texture_ids_);
     81     glBindTexture(GL_TEXTURE_2D, texture_ids_[1]);
     82 
     83     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     84     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     85     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     86     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     87 
     88     glGenFramebuffers(1, &framebuffer_id_);
     89     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
     90     glFramebufferTexture2D(GL_FRAMEBUFFER,
     91                            GL_COLOR_ATTACHMENT0,
     92                            GL_TEXTURE_2D,
     93                            texture_ids_[1],
     94                            0);
     95   }
     96 
     97   virtual void TearDown() {
     98     glDeleteTextures(2, texture_ids_);
     99     glDeleteFramebuffers(1, &framebuffer_id_);
    100 
    101     gl_.Destroy();
    102   }
    103 
    104   scoped_refptr<ImageManager> image_manager_;
    105   scoped_ptr<MockGpuMemoryBufferFactory> gpu_memory_buffer_factory_;
    106   GLManager gl_;
    107   GLuint texture_ids_[2];
    108   GLuint framebuffer_id_;
    109 };
    110 
    111 // An end to end test that tests the whole GpuMemoryBuffer lifecycle.
    112 TEST_F(MockGpuMemoryBufferTest, Lifecycle) {
    113   size_t bytes = kImageWidth * kImageHeight * kImageBytesPerPixel;
    114   uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
    115 
    116   // Buffer is owned and freed by GpuMemoryBufferTracker.
    117   StrictMock<MockGpuMemoryBuffer>* gpu_memory_buffer =
    118       new StrictMock<MockGpuMemoryBuffer>(kImageWidth, kImageHeight);
    119   base::SharedMemory shared_memory;
    120   shared_memory.CreateAnonymous(bytes);
    121 
    122   base::SharedMemoryHandle duped_shared_memory_handle;
    123   shared_memory.ShareToProcess(base::GetCurrentProcessHandle(),
    124                                &duped_shared_memory_handle);
    125   gfx::GpuMemoryBufferHandle handle;
    126   handle.type = gfx::SHARED_MEMORY_BUFFER;
    127   handle.handle = duped_shared_memory_handle;
    128 
    129   EXPECT_CALL(*gpu_memory_buffer_factory_.get(), CreateGpuMemoryBuffer(
    130       kImageWidth, kImageHeight, GL_RGBA8_OES))
    131       .Times(1)
    132       .WillOnce(Return(gpu_memory_buffer))
    133       .RetiresOnSaturation();
    134   EXPECT_CALL(*gpu_memory_buffer, GetHandle())
    135       .Times(1)
    136       .WillOnce(Return(handle))
    137       .RetiresOnSaturation();
    138 
    139   // Create the image. This should add the image ID to the ImageManager.
    140   GLuint image_id = glCreateImageCHROMIUM(
    141       kImageWidth, kImageHeight, GL_RGBA8_OES);
    142   EXPECT_NE(0u, image_id);
    143   EXPECT_TRUE(image_manager_->LookupImage(image_id) != NULL);
    144 
    145   EXPECT_CALL(*gpu_memory_buffer, IsMapped())
    146       .WillOnce(Return(false))
    147       .RetiresOnSaturation();
    148 
    149   shared_memory.Map(bytes);
    150   EXPECT_TRUE(shared_memory.memory());
    151 
    152   EXPECT_CALL(*gpu_memory_buffer, Map(_, _))
    153       .Times(1)
    154       .WillOnce(SetArgPointee<1>(shared_memory.memory()))
    155       .RetiresOnSaturation();
    156   uint8* mapped_buffer = static_cast<uint8*>(
    157       glMapImageCHROMIUM(image_id, GL_READ_WRITE));
    158   ASSERT_TRUE(mapped_buffer != NULL);
    159 
    160   // Assign a value to each pixel.
    161   int stride = kImageWidth * kImageBytesPerPixel;
    162   for (int x = 0; x < kImageWidth; ++x) {
    163     for (int y = 0; y < kImageHeight; ++y) {
    164       mapped_buffer[y * stride + x * kImageBytesPerPixel + 0] = pixels[0];
    165       mapped_buffer[y * stride + x * kImageBytesPerPixel + 1] = pixels[1];
    166       mapped_buffer[y * stride + x * kImageBytesPerPixel + 2] = pixels[2];
    167       mapped_buffer[y * stride + x * kImageBytesPerPixel + 3] = pixels[3];
    168     }
    169   }
    170 
    171   EXPECT_CALL(*gpu_memory_buffer, IsMapped())
    172       .WillOnce(Return(true))
    173       .RetiresOnSaturation();
    174 
    175   // Unmap the image.
    176   EXPECT_CALL(*gpu_memory_buffer, Unmap())
    177       .Times(1)
    178       .RetiresOnSaturation();
    179   glUnmapImageCHROMIUM(image_id);
    180 
    181   // Bind the texture and the image.
    182   glBindTexture(GL_TEXTURE_2D, texture_ids_[0]);
    183   glBindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
    184 
    185   // Copy texture so we can verify result using CheckPixels.
    186   glCopyTextureCHROMIUM(GL_TEXTURE_2D,
    187                         texture_ids_[0],
    188                         texture_ids_[1],
    189                         0,
    190                         GL_RGBA,
    191                         GL_UNSIGNED_BYTE);
    192   EXPECT_TRUE(glGetError() == GL_NO_ERROR);
    193 
    194   // Check if pixels match the values that were assigned to the mapped buffer.
    195   GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixels);
    196   EXPECT_TRUE(GL_NO_ERROR == glGetError());
    197 
    198   // Release the image.
    199   glReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
    200 
    201   // Destroy the image.
    202   EXPECT_CALL(*gpu_memory_buffer, Die())
    203       .Times(1)
    204       .RetiresOnSaturation();
    205   glDestroyImageCHROMIUM(image_id);
    206 }
    207 
    208 }  // namespace gles2
    209 }  // namespace gpu
    210