1 // Copyright 2018 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 "gpu/command_buffer/service/texture_owner.h"
6
7 #include <stdint.h>
8 #include <memory>
9 #include <utility>
10
11 #include "base/test/task_environment.h"
12 #include "gpu/command_buffer/service/abstract_texture.h"
13 #include "gpu/command_buffer/service/image_reader_gl_owner.h"
14 #include "gpu/command_buffer/service/mock_abstract_texture.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/gl/gl_bindings.h"
17 #include "ui/gl/gl_context_egl.h"
18 #include "ui/gl/gl_surface_egl.h"
19 #include "ui/gl/init/gl_factory.h"
20
21 namespace gpu {
22
23 class ImageReaderGLOwnerTest : public testing::Test {
24 public:
ImageReaderGLOwnerTest()25 ImageReaderGLOwnerTest() {}
~ImageReaderGLOwnerTest()26 ~ImageReaderGLOwnerTest() override {}
27
28 protected:
SetUp()29 void SetUp() override {
30 if (!IsImageReaderSupported())
31 return;
32
33 gl::init::InitializeStaticGLBindingsImplementation(
34 gl::kGLImplementationEGLGLES2, false);
35 gl::init::InitializeGLOneOffPlatformImplementation(false, false, true);
36
37 surface_ = new gl::PbufferGLSurfaceEGL(gfx::Size(320, 240));
38 surface_->Initialize();
39
40 share_group_ = new gl::GLShareGroup();
41 context_ = new gl::GLContextEGL(share_group_.get());
42 context_->Initialize(surface_.get(), gl::GLContextAttribs());
43 ASSERT_TRUE(context_->MakeCurrent(surface_.get()));
44
45 // Create a texture.
46 glGenTextures(1, &texture_id_);
47
48 std::unique_ptr<MockAbstractTexture> texture =
49 std::make_unique<MockAbstractTexture>(texture_id_);
50 abstract_texture_ = texture->AsWeakPtr();
51 image_reader_ = TextureOwner::Create(std::move(texture), SecureMode());
52 }
53
SecureMode()54 virtual TextureOwner::Mode SecureMode() {
55 return TextureOwner::Mode::kAImageReaderInsecure;
56 }
57
TearDown()58 void TearDown() override {
59 if (texture_id_ && context_->MakeCurrent(surface_.get()))
60 glDeleteTextures(1, &texture_id_);
61 image_reader_ = nullptr;
62 context_ = nullptr;
63 share_group_ = nullptr;
64 surface_ = nullptr;
65 gl::init::ShutdownGL(false);
66 }
67
IsImageReaderSupported() const68 bool IsImageReaderSupported() const {
69 return base::android::AndroidImageReader::GetInstance().IsSupported();
70 }
71
72 scoped_refptr<TextureOwner> image_reader_;
73 GLuint texture_id_ = 0;
74
75 base::WeakPtr<MockAbstractTexture> abstract_texture_;
76
77 scoped_refptr<gl::GLContext> context_;
78 scoped_refptr<gl::GLShareGroup> share_group_;
79 scoped_refptr<gl::GLSurface> surface_;
80 base::test::TaskEnvironment task_environment_;
81 };
82
TEST_F(ImageReaderGLOwnerTest,ImageReaderObjectCreation)83 TEST_F(ImageReaderGLOwnerTest, ImageReaderObjectCreation) {
84 if (!IsImageReaderSupported())
85 return;
86
87 ASSERT_TRUE(image_reader_);
88 }
89
TEST_F(ImageReaderGLOwnerTest,ScopedJavaSurfaceCreation)90 TEST_F(ImageReaderGLOwnerTest, ScopedJavaSurfaceCreation) {
91 if (!IsImageReaderSupported())
92 return;
93
94 gl::ScopedJavaSurface temp = image_reader_->CreateJavaSurface();
95 ASSERT_TRUE(temp.IsValid());
96 }
97
98 // Verify that ImageReaderGLOwner creates a bindable GL texture, and deletes
99 // it during destruction.
TEST_F(ImageReaderGLOwnerTest,GLTextureIsCreatedAndDestroyed)100 TEST_F(ImageReaderGLOwnerTest, GLTextureIsCreatedAndDestroyed) {
101 if (!IsImageReaderSupported())
102 return;
103
104 // |texture_id| should not work anymore after we delete image_reader_.
105 image_reader_ = nullptr;
106 EXPECT_FALSE(abstract_texture_);
107 }
108
109 // Make sure that image_reader_ remembers the correct context and surface.
TEST_F(ImageReaderGLOwnerTest,ContextAndSurfaceAreCaptured)110 TEST_F(ImageReaderGLOwnerTest, ContextAndSurfaceAreCaptured) {
111 if (!IsImageReaderSupported())
112 return;
113
114 ASSERT_EQ(context_, image_reader_->GetContext());
115 ASSERT_EQ(surface_, image_reader_->GetSurface());
116 }
117
118 // Verify that destruction works even if some other context is current.
TEST_F(ImageReaderGLOwnerTest,DestructionWorksWithWrongContext)119 TEST_F(ImageReaderGLOwnerTest, DestructionWorksWithWrongContext) {
120 if (!IsImageReaderSupported())
121 return;
122
123 scoped_refptr<gl::GLSurface> new_surface(
124 new gl::PbufferGLSurfaceEGL(gfx::Size(320, 240)));
125 new_surface->Initialize();
126
127 scoped_refptr<gl::GLShareGroup> new_share_group(new gl::GLShareGroup());
128 scoped_refptr<gl::GLContext> new_context(
129 new gl::GLContextEGL(new_share_group.get()));
130 new_context->Initialize(new_surface.get(), gl::GLContextAttribs());
131 ASSERT_TRUE(new_context->MakeCurrent(new_surface.get()));
132
133 image_reader_ = nullptr;
134 EXPECT_FALSE(abstract_texture_);
135
136 // |new_context| should still be current.
137 ASSERT_TRUE(new_context->IsCurrent(new_surface.get()));
138
139 new_context = nullptr;
140 new_share_group = nullptr;
141 new_surface = nullptr;
142 }
143
144 // The max number of images used by the ImageReader must be 1 for non-Surface
145 // control.
TEST_F(ImageReaderGLOwnerTest,MaxImageExpectation)146 TEST_F(ImageReaderGLOwnerTest, MaxImageExpectation) {
147 if (!IsImageReaderSupported())
148 return;
149 EXPECT_EQ(static_cast<ImageReaderGLOwner*>(image_reader_.get())
150 ->max_images_for_testing(),
151 1);
152 }
153
154 class ImageReaderGLOwnerSecureSurfaceControlTest
155 : public ImageReaderGLOwnerTest {
156 public:
SecureMode()157 TextureOwner::Mode SecureMode() final {
158 return TextureOwner::Mode::kAImageReaderSecureSurfaceControl;
159 }
160 };
161
TEST_F(ImageReaderGLOwnerSecureSurfaceControlTest,CreatesSecureAImageReader)162 TEST_F(ImageReaderGLOwnerSecureSurfaceControlTest, CreatesSecureAImageReader) {
163 if (!IsImageReaderSupported())
164 return;
165
166 ASSERT_TRUE(image_reader_);
167 auto* a_image_reader = static_cast<ImageReaderGLOwner*>(image_reader_.get())
168 ->image_reader_for_testing();
169 int32_t format = AIMAGE_FORMAT_YUV_420_888;
170 base::android::AndroidImageReader::GetInstance().AImageReader_getFormat(
171 a_image_reader, &format);
172 EXPECT_EQ(format, AIMAGE_FORMAT_PRIVATE);
173 }
174
175 // The max number of images used by the ImageReader must be 3 for Surface
176 // control.
TEST_F(ImageReaderGLOwnerSecureSurfaceControlTest,MaxImageExpectation)177 TEST_F(ImageReaderGLOwnerSecureSurfaceControlTest, MaxImageExpectation) {
178 if (!IsImageReaderSupported())
179 return;
180 EXPECT_EQ(static_cast<ImageReaderGLOwner*>(image_reader_.get())
181 ->max_images_for_testing(),
182 3);
183 }
184
185 class ImageReaderGLOwnerInsecureSurfaceControlTest
186 : public ImageReaderGLOwnerTest {
187 public:
SecureMode()188 TextureOwner::Mode SecureMode() final {
189 return TextureOwner::Mode::kAImageReaderInsecureSurfaceControl;
190 }
191 };
192
193 // The max number of images used by the ImageReader must be 3 for Surface
194 // control.
TEST_F(ImageReaderGLOwnerInsecureSurfaceControlTest,MaxImageExpectation)195 TEST_F(ImageReaderGLOwnerInsecureSurfaceControlTest, MaxImageExpectation) {
196 if (!IsImageReaderSupported())
197 return;
198 EXPECT_EQ(static_cast<ImageReaderGLOwner*>(image_reader_.get())
199 ->max_images_for_testing(),
200 3);
201 }
202
203 } // namespace gpu
204