Windows should animate when they are about to get docked at screen edges.
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_gpu_memory_buffer_unittests.cc
blob9c9d5ab1f1b7319e95dc88f7cc7da7af122d9565
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.
5 #include <GLES2/gl2.h>
6 #include <GLES2/gl2chromium.h>
7 #include <GLES2/gl2ext.h>
8 #include <GLES2/gl2extchromium.h>
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/service/image_manager.h"
15 #include "gpu/command_buffer/tests/gl_manager.h"
16 #include "gpu/command_buffer/tests/gl_test_utils.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/gl/gl_image.h"
21 using testing::_;
22 using testing::IgnoreResult;
23 using testing::InvokeWithoutArgs;
24 using testing::Invoke;
25 using testing::Return;
26 using testing::SetArgPointee;
27 using testing::StrictMock;
29 namespace gpu {
30 namespace gles2 {
32 static const int kImageWidth = 32;
33 static const int kImageHeight = 32;
34 static const int kImageBytesPerPixel = 4;
36 class MockGpuMemoryBuffer : public gfx::GpuMemoryBuffer {
37 public:
38 MockGpuMemoryBuffer(int width, int height) {}
39 virtual ~MockGpuMemoryBuffer() {
40 Die();
43 MOCK_METHOD2(Map, void(gfx::GpuMemoryBuffer::AccessMode, void**));
44 MOCK_METHOD0(Unmap, void());
45 MOCK_CONST_METHOD0(IsMapped, bool());
46 MOCK_CONST_METHOD0(GetStride, uint32());
47 MOCK_CONST_METHOD0(GetHandle, gfx::GpuMemoryBufferHandle());
48 MOCK_METHOD0(Die, void());
50 private:
51 DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBuffer);
54 class MockImageFactory : public ImageFactory {
55 public:
56 MockImageFactory(ImageManager* image_manager) {}
57 virtual ~MockImageFactory() {}
59 MOCK_METHOD4(CreateGpuMemoryBufferMock, gfx::GpuMemoryBuffer*(
60 int width, int height, GLenum internalformat, unsigned* image_id));
61 MOCK_METHOD1(DeleteGpuMemoryBuffer, void(unsigned));
62 // Workaround for mocking methods that return scoped_ptrs
63 virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer(
64 int width, int height, GLenum internalformat,
65 unsigned* image_id) OVERRIDE {
66 return scoped_ptr<gfx::GpuMemoryBuffer>(CreateGpuMemoryBufferMock(
67 width, height, internalformat, image_id));
70 private:
71 DISALLOW_COPY_AND_ASSIGN(MockImageFactory);
74 class MockGpuMemoryBufferTest : public testing::Test {
75 protected:
76 virtual void SetUp() {
77 GLManager::Options options;
78 image_manager_ = new ImageManager;
79 image_factory_.reset(
80 new StrictMock<MockImageFactory>(image_manager_.get()));
81 options.image_manager = image_manager_.get();
82 options.image_factory = image_factory_.get();
84 gl_.Initialize(options);
85 gl_.MakeCurrent();
87 glGenTextures(2, texture_ids_);
88 glBindTexture(GL_TEXTURE_2D, texture_ids_[1]);
90 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
91 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
92 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
93 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
95 glGenFramebuffers(1, &framebuffer_id_);
96 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
97 glFramebufferTexture2D(GL_FRAMEBUFFER,
98 GL_COLOR_ATTACHMENT0,
99 GL_TEXTURE_2D,
100 texture_ids_[1],
104 virtual void TearDown() {
105 glDeleteTextures(2, texture_ids_);
106 glDeleteFramebuffers(1, &framebuffer_id_);
108 gl_.Destroy();
111 scoped_ptr<StrictMock<MockImageFactory> > image_factory_;
112 scoped_refptr<ImageManager> image_manager_;
113 GLManager gl_;
114 GLuint texture_ids_[2];
115 GLuint framebuffer_id_;
118 // An end to end test that tests the whole GpuMemoryBuffer lifecycle.
119 TEST_F(MockGpuMemoryBufferTest, Lifecycle) {
120 size_t bytes = kImageWidth * kImageHeight * kImageBytesPerPixel;
121 uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
123 // Buffer is owned and freed by GpuMemoryBufferTracker.
124 StrictMock<MockGpuMemoryBuffer>* gpu_memory_buffer =
125 new StrictMock<MockGpuMemoryBuffer>(kImageWidth, kImageHeight);
126 base::SharedMemory shared_memory;
127 shared_memory.CreateAnonymous(bytes);
129 base::SharedMemoryHandle duped_shared_memory_handle;
130 shared_memory.ShareToProcess(base::GetCurrentProcessHandle(),
131 &duped_shared_memory_handle);
132 gfx::GpuMemoryBufferHandle handle;
133 handle.type = gfx::SHARED_MEMORY_BUFFER;
134 handle.handle = duped_shared_memory_handle;
136 const GLuint kImageId = 345u;
138 EXPECT_CALL(*image_factory_.get(), CreateGpuMemoryBufferMock(
139 kImageWidth, kImageHeight, GL_RGBA8_OES, _))
140 .Times(1)
141 .WillOnce(DoAll(SetArgPointee<3>(kImageId), Return(gpu_memory_buffer)))
142 .RetiresOnSaturation();
144 // Create the GLImage and insert it into the ImageManager, which
145 // would be done within CreateGpuMemoryBufferMock if it weren't a mock.
146 GLuint image_id = glCreateImageCHROMIUM(
147 kImageWidth, kImageHeight, GL_RGBA8_OES);
148 EXPECT_EQ(kImageId, image_id);
150 EXPECT_CALL(*gpu_memory_buffer, GetHandle())
151 .WillOnce(Return(handle))
152 .RetiresOnSaturation();
154 gfx::Size size(kImageWidth, kImageHeight);
155 scoped_refptr<gfx::GLImage> gl_image(
156 gfx::GLImage::CreateGLImageForGpuMemoryBuffer(
157 gpu_memory_buffer->GetHandle(), size));
158 image_manager_->AddImage(gl_image.get(), image_id);
160 EXPECT_CALL(*gpu_memory_buffer, IsMapped())
161 .WillOnce(Return(false))
162 .RetiresOnSaturation();
164 shared_memory.Map(bytes);
165 EXPECT_TRUE(shared_memory.memory());
167 EXPECT_CALL(*gpu_memory_buffer, Map(_, _))
168 .Times(1)
169 .WillOnce(SetArgPointee<1>(shared_memory.memory()))
170 .RetiresOnSaturation();
171 uint8* mapped_buffer = static_cast<uint8*>(
172 glMapImageCHROMIUM(image_id, GL_READ_WRITE));
173 ASSERT_TRUE(mapped_buffer != NULL);
175 // Assign a value to each pixel.
176 int stride = kImageWidth * kImageBytesPerPixel;
177 for (int x = 0; x < kImageWidth; ++x) {
178 for (int y = 0; y < kImageHeight; ++y) {
179 mapped_buffer[y * stride + x * kImageBytesPerPixel + 0] = pixels[0];
180 mapped_buffer[y * stride + x * kImageBytesPerPixel + 1] = pixels[1];
181 mapped_buffer[y * stride + x * kImageBytesPerPixel + 2] = pixels[2];
182 mapped_buffer[y * stride + x * kImageBytesPerPixel + 3] = pixels[3];
186 EXPECT_CALL(*gpu_memory_buffer, IsMapped())
187 .WillOnce(Return(true))
188 .RetiresOnSaturation();
190 // Unmap the image.
191 EXPECT_CALL(*gpu_memory_buffer, Unmap())
192 .Times(1)
193 .RetiresOnSaturation();
194 glUnmapImageCHROMIUM(image_id);
196 // Bind the texture and the image.
197 glBindTexture(GL_TEXTURE_2D, texture_ids_[0]);
198 glBindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
200 // Copy texture so we can verify result using CheckPixels.
201 glCopyTextureCHROMIUM(GL_TEXTURE_2D,
202 texture_ids_[0],
203 texture_ids_[1],
205 GL_RGBA,
206 GL_UNSIGNED_BYTE);
207 EXPECT_TRUE(glGetError() == GL_NO_ERROR);
209 // Check if pixels match the values that were assigned to the mapped buffer.
210 GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixels);
211 EXPECT_TRUE(GL_NO_ERROR == glGetError());
213 // Release the image.
214 glReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
216 // Destroy the image.
217 EXPECT_CALL(*gpu_memory_buffer, Die())
218 .Times(1)
219 .RetiresOnSaturation();
221 EXPECT_CALL(*image_factory_.get(), DeleteGpuMemoryBuffer(image_id))
222 .Times(1)
223 .RetiresOnSaturation();
225 glDestroyImageCHROMIUM(image_id);
228 } // namespace gles2
229 } // namespace gpu