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