1// Copyright (c) 2012 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#ifndef GL_GLEXT_PROTOTYPES
6#define GL_GLEXT_PROTOTYPES
7#endif
8
9#include <GLES2/gl2.h>
10#include <GLES2/gl2ext.h>
11#include <GLES2/gl2extchromium.h>
12
13#include "gpu/command_buffer/tests/gl_manager.h"
14#include "gpu/command_buffer/tests/gl_test_utils.h"
15#include "testing/gmock/include/gmock/gmock.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18namespace gpu {
19
20// A collection of tests that exercise the GL_CHROMIUM_copy_texture extension.
21class GLCopyTextureCHROMIUMTest : public testing::Test {
22 protected:
23  virtual void SetUp() {
24    gl_.Initialize(GLManager::Options());
25
26    glGenTextures(2, textures_);
27    glBindTexture(GL_TEXTURE_2D, textures_[1]);
28
29    // Some drivers (NVidia/SGX) require texture settings to be a certain way or
30    // they won't report FRAMEBUFFER_COMPLETE.
31    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
32    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
33    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
34    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
35
36    glGenFramebuffers(1, &framebuffer_id_);
37    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
38    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
39                           textures_[1], 0);
40  }
41
42  virtual void TearDown() {
43    glDeleteTextures(2, textures_);
44    glDeleteFramebuffers(1, &framebuffer_id_);
45    gl_.Destroy();
46  }
47
48  GLManager gl_;
49  GLuint textures_[2];
50  GLuint framebuffer_id_;
51};
52
53// Test to ensure that the basic functionality of the extension works.
54TEST_F(GLCopyTextureCHROMIUMTest, Basic) {
55  uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
56
57  glBindTexture(GL_TEXTURE_2D, textures_[0]);
58  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
59               pixels);
60
61  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
62                        GL_UNSIGNED_BYTE);
63  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
64
65  // Check the FB is still bound.
66  GLint value = 0;
67  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
68  GLuint fb_id = value;
69  EXPECT_EQ(framebuffer_id_, fb_id);
70
71  // Check that FB is complete.
72  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
73            glCheckFramebufferStatus(GL_FRAMEBUFFER));
74
75  GLTestHelper::CheckPixels(0, 0, 1, 1, 0, pixels);
76  EXPECT_TRUE(GL_NO_ERROR == glGetError());
77}
78
79TEST_F(GLCopyTextureCHROMIUMTest, InternalFormat) {
80  GLint src_formats[] = {GL_ALPHA,     GL_RGB,             GL_RGBA,
81                         GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
82  GLint dest_formats[] = {GL_RGB, GL_RGBA};
83
84  for (size_t src_index = 0; src_index < arraysize(src_formats); src_index++) {
85    for (size_t dest_index = 0; dest_index < arraysize(dest_formats);
86         dest_index++) {
87      glBindTexture(GL_TEXTURE_2D, textures_[0]);
88      glTexImage2D(GL_TEXTURE_2D,
89                   0,
90                   src_formats[src_index],
91                   1,
92                   1,
93                   0,
94                   src_formats[src_index],
95                   GL_UNSIGNED_BYTE,
96                   NULL);
97      EXPECT_TRUE(GL_NO_ERROR == glGetError());
98
99      glCopyTextureCHROMIUM(GL_TEXTURE_2D,
100                            textures_[0],
101                            textures_[1],
102                            0,
103                            dest_formats[dest_index],
104                            GL_UNSIGNED_BYTE);
105      EXPECT_TRUE(GL_NO_ERROR == glGetError()) << "src_index:" << src_index
106                                               << " dest_index:" << dest_index;
107    }
108  }
109}
110
111TEST_F(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
112  glBindTexture(GL_TEXTURE_2D, textures_[0]);
113  glTexImage2D(
114      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
115  EXPECT_TRUE(GL_NO_ERROR == glGetError());
116
117  // Check unsupported format reports error.
118  GLint unsupported_dest_formats[] = {GL_ALPHA, GL_LUMINANCE,
119                                      GL_LUMINANCE_ALPHA};
120  for (size_t dest_index = 0; dest_index < arraysize(unsupported_dest_formats);
121       dest_index++) {
122    glCopyTextureCHROMIUM(GL_TEXTURE_2D,
123                          textures_[0],
124                          textures_[1],
125                          0,
126                          unsupported_dest_formats[dest_index],
127                          GL_UNSIGNED_BYTE);
128    EXPECT_TRUE(GL_INVALID_OPERATION == glGetError())
129        << "dest_index:" << dest_index;
130  }
131}
132
133// Test to ensure that the destination texture is redefined if the properties
134// are different.
135TEST_F(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
136  uint8 pixels[4 * 4] = {255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u,
137                         255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u};
138
139  glBindTexture(GL_TEXTURE_2D, textures_[0]);
140  glTexImage2D(
141      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
142
143  glBindTexture(GL_TEXTURE_2D, textures_[1]);
144  glTexImage2D(GL_TEXTURE_2D,
145               0,
146               GL_BGRA_EXT,
147               1,
148               1,
149               0,
150               GL_BGRA_EXT,
151               GL_UNSIGNED_BYTE,
152               pixels);
153  EXPECT_TRUE(GL_NO_ERROR == glGetError());
154
155  // GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
156  glTexSubImage2D(
157      GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
158  EXPECT_TRUE(GL_INVALID_OPERATION == glGetError());
159  // GL_INVALID_VALUE due to bad dimensions.
160  glTexSubImage2D(
161      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
162  EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
163
164  // If the dest texture has different properties, glCopyTextureCHROMIUM()
165  // redefines them.
166  glCopyTextureCHROMIUM(
167      GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA, GL_UNSIGNED_BYTE);
168  EXPECT_TRUE(GL_NO_ERROR == glGetError());
169
170  // glTexSubImage2D() succeeds because textures_[1] is redefined into 2x2
171  // dimension and GL_RGBA format.
172  glBindTexture(GL_TEXTURE_2D, textures_[1]);
173  glTexSubImage2D(
174      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
175  EXPECT_TRUE(GL_NO_ERROR == glGetError());
176
177  // Check the FB is still bound.
178  GLint value = 0;
179  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
180  GLuint fb_id = value;
181  EXPECT_EQ(framebuffer_id_, fb_id);
182
183  // Check that FB is complete.
184  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
185            glCheckFramebufferStatus(GL_FRAMEBUFFER));
186
187  GLTestHelper::CheckPixels(1, 1, 1, 1, 0, &pixels[12]);
188  EXPECT_TRUE(GL_NO_ERROR == glGetError());
189}
190
191// Test that the extension respects the flip-y pixel storage setting.
192TEST_F(GLCopyTextureCHROMIUMTest, FlipY) {
193  uint8 pixels[2][2][4];
194  for (int x = 0; x < 2; ++x) {
195    for (int y = 0; y < 2; ++y) {
196      pixels[y][x][0] = x + y;
197      pixels[y][x][1] = x + y;
198      pixels[y][x][2] = x + y;
199      pixels[y][x][3] = 255u;
200    }
201  }
202
203  glBindTexture(GL_TEXTURE_2D, textures_[0]);
204  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
205               pixels);
206
207  glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
208  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
209                        GL_UNSIGNED_BYTE);
210  EXPECT_TRUE(GL_NO_ERROR == glGetError());
211
212  uint8 copied_pixels[2][2][4] = {{{0}}};
213  glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
214  for (int x = 0; x < 2; ++x) {
215    for (int y = 0; y < 2; ++y) {
216      EXPECT_EQ(pixels[1-y][x][0], copied_pixels[y][x][0]);
217      EXPECT_EQ(pixels[1-y][x][1], copied_pixels[y][x][1]);
218      EXPECT_EQ(pixels[1-y][x][2], copied_pixels[y][x][2]);
219      EXPECT_EQ(pixels[1-y][x][3], copied_pixels[y][x][3]);
220    }
221  }
222
223  EXPECT_TRUE(GL_NO_ERROR == glGetError());
224}
225
226// Test that the extension respects the GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM
227// storage setting.
228TEST_F(GLCopyTextureCHROMIUMTest, PremultiplyAlpha) {
229  uint8 pixels[1 * 4] = { 2, 2, 2, 128 };
230
231  glBindTexture(GL_TEXTURE_2D, textures_[0]);
232  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
233               pixels);
234
235  glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
236  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
237                       GL_UNSIGNED_BYTE);
238  EXPECT_TRUE(GL_NO_ERROR == glGetError());
239
240  uint8 copied_pixels[1 * 4] = {0};
241  glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
242  EXPECT_EQ(1u, copied_pixels[0]);
243  EXPECT_EQ(1u, copied_pixels[1]);
244  EXPECT_EQ(1u, copied_pixels[2]);
245  EXPECT_EQ(128u, copied_pixels[3]);
246
247  EXPECT_TRUE(GL_NO_ERROR == glGetError());
248}
249
250// Test that the extension respects the GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM
251// storage setting.
252TEST_F(GLCopyTextureCHROMIUMTest, UnpremultiplyAlpha) {
253  uint8 pixels[1 * 4] = { 16, 16, 16, 128 };
254
255  glBindTexture(GL_TEXTURE_2D, textures_[0]);
256  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
257               pixels);
258
259  glPixelStorei(GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
260  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
261                        GL_UNSIGNED_BYTE);
262  EXPECT_TRUE(GL_NO_ERROR == glGetError());
263
264  uint8 copied_pixels[1 * 4] = {0};
265  glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
266  EXPECT_EQ(32u, copied_pixels[0]);
267  EXPECT_EQ(32u, copied_pixels[1]);
268  EXPECT_EQ(32u, copied_pixels[2]);
269  EXPECT_EQ(128u, copied_pixels[3]);
270
271  EXPECT_TRUE(GL_NO_ERROR == glGetError());
272}
273
274TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndPremultiplyAlpha) {
275  uint8 pixels[2][2][4];
276  for (int x = 0; x < 2; ++x) {
277    for (int y = 0; y < 2; ++y) {
278      uint8 color = 16 * x + 16 * y;
279      pixels[y][x][0] = color;
280      pixels[y][x][1] = color;
281      pixels[y][x][2] = color;
282      pixels[y][x][3] = 128u;
283    }
284  }
285
286  glBindTexture(GL_TEXTURE_2D, textures_[0]);
287  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
288               pixels);
289
290  glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
291  glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
292  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
293                        GL_UNSIGNED_BYTE);
294  EXPECT_TRUE(GL_NO_ERROR == glGetError());
295
296  uint8 copied_pixels[2][2][4] = {{{0}}};
297  glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
298  for (int x = 0; x < 2; ++x) {
299    for (int y = 0; y < 2; ++y) {
300      EXPECT_EQ(pixels[1-y][x][0] / 2, copied_pixels[y][x][0]);
301      EXPECT_EQ(pixels[1-y][x][1] / 2, copied_pixels[y][x][1]);
302      EXPECT_EQ(pixels[1-y][x][2] / 2, copied_pixels[y][x][2]);
303      EXPECT_EQ(pixels[1-y][x][3], copied_pixels[y][x][3]);
304    }
305  }
306
307  EXPECT_TRUE(GL_NO_ERROR == glGetError());
308}
309
310TEST_F(GLCopyTextureCHROMIUMTest, FlipYAndUnpremultiplyAlpha) {
311  uint8 pixels[2][2][4];
312  for (int x = 0; x < 2; ++x) {
313    for (int y = 0; y < 2; ++y) {
314      uint8 color = 16 * x + 16 * y;
315      pixels[y][x][0] = color;
316      pixels[y][x][1] = color;
317      pixels[y][x][2] = color;
318      pixels[y][x][3] = 128u;
319    }
320  }
321
322  glBindTexture(GL_TEXTURE_2D, textures_[0]);
323  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
324               pixels);
325
326  glPixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
327  glPixelStorei(GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, GL_TRUE);
328  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
329                        GL_UNSIGNED_BYTE);
330  EXPECT_TRUE(GL_NO_ERROR == glGetError());
331
332  uint8 copied_pixels[2][2][4] = {{{0}}};
333  glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, copied_pixels);
334  for (int x = 0; x < 2; ++x) {
335    for (int y = 0; y < 2; ++y) {
336      EXPECT_EQ(pixels[1-y][x][0] * 2, copied_pixels[y][x][0]);
337      EXPECT_EQ(pixels[1-y][x][1] * 2, copied_pixels[y][x][1]);
338      EXPECT_EQ(pixels[1-y][x][2] * 2, copied_pixels[y][x][2]);
339      EXPECT_EQ(pixels[1-y][x][3], copied_pixels[y][x][3]);
340    }
341  }
342
343  EXPECT_TRUE(GL_NO_ERROR == glGetError());
344}
345
346namespace {
347
348void glEnableDisable(GLint param, GLboolean value) {
349  if (value)
350    glEnable(param);
351  else
352    glDisable(param);
353}
354
355}  // unnamed namespace
356
357// Validate that some basic GL state is not touched upon execution of
358// the extension.
359TEST_F(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
360  uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
361
362  glBindFramebuffer(GL_FRAMEBUFFER, 0);
363
364  glBindTexture(GL_TEXTURE_2D, textures_[0]);
365  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
366               pixels);
367
368  GLboolean reference_settings[2] = { GL_TRUE, GL_FALSE };
369  for (int x = 0; x < 2; ++x) {
370    GLboolean setting = reference_settings[x];
371    glEnableDisable(GL_DEPTH_TEST, setting);
372    glEnableDisable(GL_SCISSOR_TEST, setting);
373    glEnableDisable(GL_STENCIL_TEST, setting);
374    glEnableDisable(GL_CULL_FACE, setting);
375    glEnableDisable(GL_BLEND, setting);
376    glColorMask(setting, setting, setting, setting);
377    glDepthMask(setting);
378
379    glActiveTexture(GL_TEXTURE1 + x);
380
381    glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
382                          GL_RGBA, GL_UNSIGNED_BYTE);
383    EXPECT_TRUE(GL_NO_ERROR == glGetError());
384
385    EXPECT_EQ(setting, glIsEnabled(GL_DEPTH_TEST));
386    EXPECT_EQ(setting, glIsEnabled(GL_SCISSOR_TEST));
387    EXPECT_EQ(setting, glIsEnabled(GL_STENCIL_TEST));
388    EXPECT_EQ(setting, glIsEnabled(GL_CULL_FACE));
389    EXPECT_EQ(setting, glIsEnabled(GL_BLEND));
390
391    GLboolean bool_array[4] = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE };
392    glGetBooleanv(GL_DEPTH_WRITEMASK, bool_array);
393    EXPECT_EQ(setting, bool_array[0]);
394
395    bool_array[0] = GL_FALSE;
396    glGetBooleanv(GL_COLOR_WRITEMASK, bool_array);
397    EXPECT_EQ(setting, bool_array[0]);
398    EXPECT_EQ(setting, bool_array[1]);
399    EXPECT_EQ(setting, bool_array[2]);
400    EXPECT_EQ(setting, bool_array[3]);
401
402    GLint active_texture = 0;
403    glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
404    EXPECT_EQ(GL_TEXTURE1 + x, active_texture);
405  }
406
407  EXPECT_TRUE(GL_NO_ERROR == glGetError());
408};
409
410// Verify that invocation of the extension does not modify the bound
411// texture state.
412TEST_F(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
413  // Setup the texture used for the extension invocation.
414  uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
415  glBindTexture(GL_TEXTURE_2D, textures_[0]);
416  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
417               pixels);
418
419  GLuint texture_ids[2];
420  glGenTextures(2, texture_ids);
421
422  glActiveTexture(GL_TEXTURE0);
423  glBindTexture(GL_TEXTURE_2D, texture_ids[0]);
424
425  glActiveTexture(GL_TEXTURE1);
426  glBindTexture(GL_TEXTURE_2D, texture_ids[1]);
427
428  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
429                        GL_RGBA, GL_UNSIGNED_BYTE);
430  EXPECT_TRUE(GL_NO_ERROR == glGetError());
431
432  GLint active_texture = 0;
433  glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
434  EXPECT_EQ(GL_TEXTURE1, active_texture);
435
436  GLint bound_texture = 0;
437  glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
438  EXPECT_EQ(texture_ids[1], static_cast<GLuint>(bound_texture));
439  glBindTexture(GL_TEXTURE_2D, 0);
440
441  bound_texture = 0;
442  glActiveTexture(GL_TEXTURE0);
443  glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
444  EXPECT_EQ(texture_ids[0], static_cast<GLuint>(bound_texture));
445  glBindTexture(GL_TEXTURE_2D, 0);
446
447  glDeleteTextures(2, texture_ids);
448
449  EXPECT_TRUE(GL_NO_ERROR == glGetError());
450}
451
452// Verify that invocation of the extension does not perturb the currently
453// bound FBO state.
454TEST_F(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
455  // Setup the texture used for the extension invocation.
456  uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
457  glBindTexture(GL_TEXTURE_2D, textures_[0]);
458  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
459               pixels);
460
461  GLuint texture_id;
462  glGenTextures(1, &texture_id);
463  glBindTexture(GL_TEXTURE_2D, texture_id);
464  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
465               0);
466
467  GLuint renderbuffer_id;
468  glGenRenderbuffers(1, &renderbuffer_id);
469  glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_id);
470  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 1, 1);
471
472  GLuint framebuffer_id;
473  glGenFramebuffers(1, &framebuffer_id);
474  glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id);
475  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
476                         texture_id, 0);
477  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
478                            GL_RENDERBUFFER, renderbuffer_id);
479  EXPECT_TRUE(
480      GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER));
481
482  // Test that we can write to the bound framebuffer
483  uint8 expected_color[4] = { 255u, 255u, 0, 255u };
484  glClearColor(1.0, 1.0, 0, 1.0);
485  glClear(GL_COLOR_BUFFER_BIT);
486  GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color);
487
488  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
489                        GL_RGBA, GL_UNSIGNED_BYTE);
490  EXPECT_TRUE(GL_NO_ERROR == glGetError());
491
492  EXPECT_TRUE(glIsFramebuffer(framebuffer_id));
493
494  // Ensure that reading from the framebuffer produces correct pixels.
495  GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color);
496
497  uint8 expected_color2[4] = { 255u, 0, 255u, 255u };
498  glClearColor(1.0, 0, 1.0, 1.0);
499  glClear(GL_COLOR_BUFFER_BIT);
500  GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color2);
501
502  GLint bound_fbo = 0;
503  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
504  EXPECT_EQ(framebuffer_id, static_cast<GLuint>(bound_fbo));
505
506  GLint fbo_params = 0;
507  glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
508                                        GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
509                                        &fbo_params);
510  EXPECT_EQ(GL_TEXTURE, fbo_params);
511
512  fbo_params = 0;
513  glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
514                                        GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
515                                        &fbo_params);
516  EXPECT_EQ(texture_id, static_cast<GLuint>(fbo_params));
517
518  fbo_params = 0;
519  glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
520                                        GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
521                                        &fbo_params);
522  EXPECT_EQ(GL_RENDERBUFFER, fbo_params);
523
524  fbo_params = 0;
525  glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
526                                        GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
527                                        &fbo_params);
528  EXPECT_EQ(renderbuffer_id, static_cast<GLuint>(fbo_params));
529
530  glDeleteRenderbuffers(1, &renderbuffer_id);
531  glDeleteTextures(1, &texture_id);
532  glDeleteFramebuffers(1, &framebuffer_id);
533
534  EXPECT_TRUE(GL_NO_ERROR == glGetError());
535}
536
537TEST_F(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
538  // unbind the one created in setup.
539  glBindFramebuffer(GL_FRAMEBUFFER, 0);
540  glBindTexture(GL_TEXTURE_2D, 0);
541
542  GLManager gl2;
543  GLManager::Options options;
544  options.size = gfx::Size(16, 16);
545  options.share_group_manager = &gl_;
546  gl2.Initialize(options);
547  gl_.MakeCurrent();
548
549  static const char* v_shader_str =
550      "attribute vec4 g_Position;\n"
551      "void main()\n"
552      "{\n"
553      "   gl_Position = g_Position;\n"
554      "}\n";
555  static const char* f_shader_str =
556      "precision mediump float;\n"
557      "void main()\n"
558      "{\n"
559      "  gl_FragColor = vec4(0,1,0,1);\n"
560      "}\n";
561
562  GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
563  glUseProgram(program);
564  GLuint position_loc = glGetAttribLocation(program, "g_Position");
565  glFlush();
566
567  // Delete program from other context.
568  gl2.MakeCurrent();
569  glDeleteProgram(program);
570  EXPECT_TRUE(GL_NO_ERROR == glGetError());
571  glFlush();
572
573  // Program should still be usable on this context.
574  gl_.MakeCurrent();
575
576  GLTestHelper::SetupUnitQuad(position_loc);
577
578  // test using program before
579  uint8 expected[] = { 0, 255, 0, 255, };
580  uint8 zero[] = { 0, 0, 0, 0, };
581  glClear(GL_COLOR_BUFFER_BIT);
582  EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero));
583  glDrawArrays(GL_TRIANGLES, 0, 6);
584  EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected));
585
586  // Call copyTextureCHROMIUM
587  uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
588  glBindTexture(GL_TEXTURE_2D, textures_[0]);
589  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
590               pixels);
591  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
592                        GL_UNSIGNED_BYTE);
593
594  // test using program after
595  glClear(GL_COLOR_BUFFER_BIT);
596  EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero));
597  glDrawArrays(GL_TRIANGLES, 0, 6);
598  EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected));
599
600  EXPECT_TRUE(GL_NO_ERROR == glGetError());
601
602  gl2.MakeCurrent();
603  gl2.Destroy();
604  gl_.MakeCurrent();
605}
606
607// Test that glCopyTextureCHROMIUM doesn't leak uninitialized textures.
608TEST_F(GLCopyTextureCHROMIUMTest, UninitializedSource) {
609  const GLsizei kWidth = 64, kHeight = 64;
610  glBindTexture(GL_TEXTURE_2D, textures_[0]);
611  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight,
612               0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
613
614  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, GL_RGBA,
615                        GL_UNSIGNED_BYTE);
616  EXPECT_TRUE(GL_NO_ERROR == glGetError());
617
618  uint8 pixels[kHeight][kWidth][4] = {{{1}}};
619  glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
620  for (int x = 0; x < kWidth; ++x) {
621    for (int y = 0; y < kHeight; ++y) {
622      EXPECT_EQ(0, pixels[y][x][0]);
623      EXPECT_EQ(0, pixels[y][x][1]);
624      EXPECT_EQ(0, pixels[y][x][2]);
625      EXPECT_EQ(0, pixels[y][x][3]);
626    }
627  }
628
629  EXPECT_TRUE(GL_NO_ERROR == glGetError());
630}
631
632}  // namespace gpu
633