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