15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <GLES2/gl2.h>
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <GLES2/gl2chromium.h>
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <GLES2/gl2ext.h>
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <GLES2/gl2extchromium.h>
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/ref_counted.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/process/process_handle.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h"
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "gpu/command_buffer/service/command_buffer_service.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/service/image_manager.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/tests/gl_manager.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/tests/gl_test_utils.h"
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gl/gl_image.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using testing::_;
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using testing::IgnoreResult;
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using testing::InvokeWithoutArgs;
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using testing::Invoke;
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using testing::Return;
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using testing::SetArgPointee;
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using testing::StrictMock;
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace gpu {
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace gles2 {
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const int kImageWidth = 32;
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const int kImageHeight = 32;
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static const int kImageBytesPerPixel = 4;
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class GpuMemoryBufferTest : public testing::Test {
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) protected:
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void SetUp() {
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    gl_.Initialize(GLManager::Options());
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gl_.MakeCurrent();
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glGenTextures(2, texture_ids_);
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glBindTexture(GL_TEXTURE_2D, texture_ids_[1]);
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glGenFramebuffers(1, &framebuffer_id_);
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glFramebufferTexture2D(GL_FRAMEBUFFER,
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                           GL_COLOR_ATTACHMENT0,
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                           GL_TEXTURE_2D,
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                           texture_ids_[1],
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                           0);
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void TearDown() {
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glDeleteTextures(2, texture_ids_);
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    glDeleteFramebuffers(1, &framebuffer_id_);
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gl_.Destroy();
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GLManager gl_;
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLuint texture_ids_[2];
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLuint framebuffer_id_;
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// An end to end test that tests the whole GpuMemoryBuffer lifecycle.
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(GpuMemoryBufferTest, Lifecycle) {
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create the image. This should add the image ID to the ImageManager.
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  GLuint image_id = glCreateImageCHROMIUM(
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      kImageWidth, kImageHeight, GL_RGBA8_OES, GL_IMAGE_MAP_CHROMIUM);
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_NE(0u, image_id);
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(gl_.decoder()->GetImageManager()->LookupImage(image_id) != NULL);
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Map image for writing.
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  uint8* mapped_buffer = static_cast<uint8*>(glMapImageCHROMIUM(image_id));
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_TRUE(mapped_buffer != NULL);
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Assign a value to each pixel.
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int stride = kImageWidth * kImageBytesPerPixel;
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (int x = 0; x < kImageWidth; ++x) {
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (int y = 0; y < kImageHeight; ++y) {
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      mapped_buffer[y * stride + x * kImageBytesPerPixel + 0] = pixels[0];
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      mapped_buffer[y * stride + x * kImageBytesPerPixel + 1] = pixels[1];
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      mapped_buffer[y * stride + x * kImageBytesPerPixel + 2] = pixels[2];
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      mapped_buffer[y * stride + x * kImageBytesPerPixel + 3] = pixels[3];
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Unmap the image.
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  glUnmapImageCHROMIUM(image_id);
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Bind the texture and the image.
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glBindTexture(GL_TEXTURE_2D, texture_ids_[0]);
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  glBindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Copy texture so we can verify result using CheckPixels.
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glCopyTextureCHROMIUM(GL_TEXTURE_2D,
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        texture_ids_[0],
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        texture_ids_[1],
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        0,
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        GL_RGBA,
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        GL_UNSIGNED_BYTE);
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Check if pixels match the values that were assigned to the mapped buffer.
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixels);
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(GL_NO_ERROR == glGetError());
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Release the image.
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  glReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id);
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Destroy the image.
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  glDestroyImageCHROMIUM(image_id);
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace gles2
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace gpu
126