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