19f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
29f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// Use of this source code is governed by a BSD-style license that can be
39f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// found in the LICENSE file.
49f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
59f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev#include <stdio.h>
69f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
79f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev#include "main.h"
89f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev#include "testbase.h"
99f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev#include "utils.h"
109f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
119f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
129f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevnamespace glbench {
139f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
149f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevconst float kScreenScaleFactor = 1e6f * (WINDOW_WIDTH * WINDOW_HEIGHT) /
159f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    (1280.f * 768);
169f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
179f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevclass WindowManagerCompositingTest : public TestBase {
189f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev public:
199f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  WindowManagerCompositingTest(bool scissor)
209f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev      : scissor_(scissor),
219f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev      compositing_background_program_(0),
229f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev      compositing_foreground_program_(0) {}
239f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  virtual ~WindowManagerCompositingTest() {}
24439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  virtual bool TestFunc(uint64_t iterations);
259f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  virtual bool Run();
26f50ecb1b44db52db39768f55a03280e1fd8eeac7Alexey Marinichev  virtual const char* Name() const { return "compositing"; }
27bcad4fb80e1115af4aad4558d93be6dabf7a3f26Daniel Kurtz  virtual bool IsDrawTest() const { return true; }
28aace01b7d49e41d1bd26be3767305f57e036e0d7Daniel Kurtz  virtual const char* Unit() const { return "1280x768_fps"; }
299f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
309f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  void InitializeCompositing();
319f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  void TeardownCompositing();
329f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  void InitBaseTexture();
339f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  void UpdateTexture();
349f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  void LoadTexture();
359f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
369f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev private:
379f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  bool scissor_;
389f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  uint32_t texture_base_[WINDOW_HEIGHT*WINDOW_WIDTH];
399f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  uint32_t texture_update_[WINDOW_HEIGHT*WINDOW_WIDTH];
409f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLuint compositing_textures_[5];
419f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLuint compositing_background_program_;
429f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLuint compositing_foreground_program_;
439f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  DISALLOW_COPY_AND_ASSIGN(WindowManagerCompositingTest);
449f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev};
459f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
469f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey MarinichevTestBase* GetWindowManagerCompositingTest(bool enable_scissor) {
479f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  return new WindowManagerCompositingTest(enable_scissor);
489f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
499f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
509f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevbool WindowManagerCompositingTest::Run() {
51aace01b7d49e41d1bd26be3767305f57e036e0d7Daniel Kurtz  const char* testname = "compositing";
529f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  if (scissor_) {
539f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glScissor(0, 0, 1, 1);
549f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glEnable(GL_SCISSOR_TEST);
55aace01b7d49e41d1bd26be3767305f57e036e0d7Daniel Kurtz    testname = "compositing_no_fill";
569f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  }
579f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  InitializeCompositing();
583907fd1607fdc5ae5065adad80b35c7733fbbf7aIlja Friedel  RunTest(this, testname, kScreenScaleFactor, WINDOW_WIDTH, WINDOW_HEIGHT, true);
599f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  TeardownCompositing();
609f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  return true;
619f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
629f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
63439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedelbool WindowManagerCompositingTest::TestFunc(uint64_t iterations) {
64439ea14b8019a05cd4d3f038b4d32bca1d3fe5dcIlja H. Friedel  for (uint64_t i = 0 ; i < iterations; ++i) {
659f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
669f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
679f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // Draw the background
689f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glDisable(GL_BLEND);
699f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glDisable(GL_DEPTH_TEST);
709f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // We have to blend three textures, but we use multi-texture for this
719f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // blending, not fb blend, to avoid the external memory traffic
729f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glActiveTexture(GL_TEXTURE0);
739f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glBindTexture(GL_TEXTURE_2D, compositing_textures_[0]);
749f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glActiveTexture(GL_TEXTURE1);
759f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glBindTexture(GL_TEXTURE_2D, compositing_textures_[1]);
769f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glActiveTexture(GL_TEXTURE2);
779f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glBindTexture(GL_TEXTURE_2D, compositing_textures_[2]);
789f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // Use the right shader
799f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glUseProgram(compositing_background_program_);
809f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // Draw the quad
819f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
829f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
839f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // Use the right shader
849f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glUseProgram(compositing_foreground_program_);
859f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
869f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // Compositing is blending, so we shall blend.
879f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glEnable(GL_BLEND);
889f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // Depth test is on for window occlusion
899f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glEnable(GL_DEPTH_TEST);
909f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
919f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // Draw window number one
929f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // This update acts like a chrome webkit sw rendering update.
939f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glActiveTexture(GL_TEXTURE0);
949f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glBindTexture(GL_TEXTURE_2D, compositing_textures_[3]);
959f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    UpdateTexture();
969f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // TODO(papakipos): this LoadTexture is likely doing more CPU memory copies
979f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // than we would like.
989f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    LoadTexture();
999f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // TODO(papakipos): add color interpolation here, and modulate
1009f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // texture against it.
1019f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1029f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1039f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // Draw window number two
1049f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // This is a static window, so we don't update it.
1059f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glActiveTexture(GL_TEXTURE0);
1069f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glBindTexture(GL_TEXTURE_2D, compositing_textures_[4]);
1079f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // TODO(papakipos): add color interpolation here, and modulate
1089f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    // texture against it.
1099f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1109f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  }
1119f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  return true;
1129f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
1139f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1149f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevconst char *kBasicTextureVertexShader =
1159f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "attribute vec4 c1;"
1169f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "attribute vec4 c2;"
117a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters    "varying vec4 v1;"
1189f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "void main() {"
1199f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "    gl_Position = c1;"
120b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie    "    v1 = c2;"
1219f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "}";
1229f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1239f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevconst char *kBasicTextureFragmentShader =
1249f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "uniform sampler2D texture_sampler;"
125a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters    "varying vec4 v1;"
1269f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "void main() {"
127b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie    "    gl_FragColor = texture2D(texture_sampler, v1.st);"
1289f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "}";
1299f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1309f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey MarinichevGLuint BasicTextureShaderProgram(GLuint vertex_buffer, GLuint texture_buffer) {
1319f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLuint program = InitShaderProgram(kBasicTextureVertexShader,
1329f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                     kBasicTextureFragmentShader);
1339f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1349f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up the texture sampler
1359f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int textureSampler = glGetUniformLocation(program, "texture_sampler");
1369f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glUniform1i(textureSampler, 0);
1379f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1389f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up vertex attribute
1399f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int attribute_index = glGetAttribLocation(program, "c1");
1409f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
1419f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1429f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
1439f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1449f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up texture attribute
1459f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  attribute_index = glGetAttribLocation(program, "c2");
1469f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, texture_buffer);
1479f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1489f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
1499f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1509f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  return program;
1519f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
1529f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1539f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevconst char *kDoubleTextureBlendVertexShader =
1549f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "attribute vec4 c1;"
1559f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "attribute vec4 c2;"
1569f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "attribute vec4 c3;"
157a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters    "varying vec4 v1;"
158a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters    "varying vec4 v2;"
1599f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "void main() {"
1609f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "    gl_Position = c1;"
161b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie    "    v1 = c2;"
162b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie    "    v2 = c3;"
1639f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "}";
1649f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1659f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevconst char *kDoubleTextureBlendFragmentShader =
1669f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "uniform sampler2D texture_sampler_0;"
1679f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "uniform sampler2D texture_sampler_1;"
168a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters    "varying vec4 v1;"
169a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters    "varying vec4 v2;"
1709f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "void main() {"
171b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie    "    vec4 one = texture2D(texture_sampler_0, v1.st);"
172b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie    "    vec4 two = texture2D(texture_sampler_1, v2.st);"
1739f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "    gl_FragColor = mix(one, two, 0.5);"
1749f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    "}";
1759f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1769f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// This shader blends the three textures
1779f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey MarinichevGLuint DoubleTextureBlendShaderProgram(GLuint vertex_buffer,
1789f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                       GLuint texture_buffer_0,
1799f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                       GLuint texture_buffer_1) {
1809f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLuint program = InitShaderProgram(kDoubleTextureBlendVertexShader,
1819f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                     kDoubleTextureBlendFragmentShader);
1829f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up the texture sampler
1839f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int textureSampler0 = glGetUniformLocation(program, "texture_sampler_0");
1849f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glUniform1i(textureSampler0, 0);
1859f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int textureSampler1 = glGetUniformLocation(program, "texture_sampler_1");
1869f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glUniform1i(textureSampler1, 1);
1879f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1889f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up vertex attribute
1899f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int attribute_index = glGetAttribLocation(program, "c1");
1909f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
1919f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1929f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
1939f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
1949f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up texture attributes
1959f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  attribute_index = glGetAttribLocation(program, "c2");
1969f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_0);
1979f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1989f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
1999f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2009f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  attribute_index = glGetAttribLocation(program, "c3");
2019f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_1);
2029f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
2039f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
2049f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2059f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  return program;
2069f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
2079f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2089f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevconst char *triple_texture_blend_vertex_shader =
2099f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"attribute vec4 c1;"
2109f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"attribute vec4 c2;"
2119f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"attribute vec4 c3;"
2129f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"attribute vec4 c4;"
213a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters"varying vec4 v1;"
214a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters"varying vec4 v2;"
215a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters"varying vec4 v3;"
2169f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"void main() {"
2179f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"    gl_Position = c1;"
218b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie"    v1 = c2;"
219b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie"    v2 = c3;"
220b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie"    v3 = c4;"
2219f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"}";
2229f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2239f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevconst char *triple_texture_blend_fragment_shader =
2249f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"uniform sampler2D texture_sampler_0;"
2259f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"uniform sampler2D texture_sampler_1;"
2269f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"uniform sampler2D texture_sampler_2;"
227a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters"varying vec4 v1;"
228a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters"varying vec4 v2;"
229a1a86cbb14725f46b095671263c04289935bc8e7Kenneth Waters"varying vec4 v3;"
2309f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"void main() {"
231b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie"    vec4 one = texture2D(texture_sampler_0, v1.st);"
232b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie"    vec4 two = texture2D(texture_sampler_1, v2.st);"
233b8f4e7a20cddf76c31f3e00438b46963365c8b97Stuart Abercrombie"    vec4 three = texture2D(texture_sampler_2, v3.st);"
2349f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"    gl_FragColor = mix(mix(one, two, 0.5), three, 0.5);"
2359f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev"}";
2369f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2379f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// This shader blends the three textures
2389f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey MarinichevGLuint TripleTextureBlendShaderProgram(GLuint vertex_buffer,
2399f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                              GLuint texture_buffer_0,
2409f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                              GLuint texture_buffer_1,
2419f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                              GLuint texture_buffer_2) {
2429f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLuint program =
2439f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    InitShaderProgram(triple_texture_blend_vertex_shader,
2449f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                      triple_texture_blend_fragment_shader);
2459f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2469f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up the texture sampler
2479f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int textureSampler0 = glGetUniformLocation(program, "texture_sampler_0");
2489f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glUniform1i(textureSampler0, 0);
2499f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int textureSampler1 = glGetUniformLocation(program, "texture_sampler_1");
2509f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glUniform1i(textureSampler1, 1);
2519f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int textureSampler2 = glGetUniformLocation(program, "texture_sampler_2");
2529f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glUniform1i(textureSampler2, 2);
2539f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2549f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up vertex attribute
2559f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  int attribute_index = glGetAttribLocation(program, "c1");
2569f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
2579f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
2589f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
2599f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2609f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up texture attributes
2619f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  attribute_index = glGetAttribLocation(program, "c2");
2629f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_0);
2639f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
2649f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
2659f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2669f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  attribute_index = glGetAttribLocation(program, "c3");
2679f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_1);
2689f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
2699f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
2709f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2719f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  attribute_index = glGetAttribLocation(program, "c4");
2729f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_2);
2739f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
2749f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glEnableVertexAttribArray(attribute_index);
2759f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2769f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  return program;
2779f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
2789f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2799f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevvoid WindowManagerCompositingTest::InitializeCompositing() {
2809f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  InitBaseTexture();
2819f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2829f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glClearColor(0.f, 0.f, 0.f, 0.f);
2839f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDisable(GL_DEPTH_TEST);
2849f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDisable(GL_BLEND);
2859f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2869f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDepthFunc(GL_LEQUAL);
2879f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2889f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glGenTextures(5, compositing_textures_);
2899f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glActiveTexture(GL_TEXTURE0);
2909f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  for (int i = 0; i < 5; i++) {
2919f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glBindTexture(GL_TEXTURE_2D, compositing_textures_[i]);
2929f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
2939f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                    GL_LINEAR);
2949f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
2959f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                    GL_LINEAR);
2969f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  }
2979f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
2989f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up the vertex arrays for drawing textured quads later on.
2999f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLfloat buffer_vertex[8] = {
3009f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    -1.f, -1.f,
3019f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    1.f,  -1.f,
3029f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    -1.f, 1.f,
3039f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    1.f,  1.f,
3049f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  };
3059f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLuint vbo_vertex = SetupVBO(GL_ARRAY_BUFFER,
3069f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                               sizeof(buffer_vertex), buffer_vertex);
3079f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3089f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLfloat buffer_texture[8] = {
3099f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    0.f, 0.f,
3109f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    1.f, 0.f,
3119f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    0.f, 1.f,
3129f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    1.f, 1.f,
3139f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  };
3149f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  GLuint vbo_texture = SetupVBO(GL_ARRAY_BUFFER,
3159f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                sizeof(buffer_texture), buffer_texture);
3169f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3179f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up the static background textures.
3189f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  UpdateTexture();
3199f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  UpdateTexture();
3209f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  UpdateTexture();
3219f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Load these textures into bound texture ids and keep using them
3229f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // from there to avoid having to reload this texture every frame
3239f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glActiveTexture(GL_TEXTURE0);
3249f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindTexture(GL_TEXTURE_2D, compositing_textures_[0]);
3259f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  LoadTexture();
3269f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glActiveTexture(GL_TEXTURE1);
3279f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindTexture(GL_TEXTURE_2D, compositing_textures_[1]);
3289f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  LoadTexture();
3299f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glActiveTexture(GL_TEXTURE2);
3309f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindTexture(GL_TEXTURE_2D, compositing_textures_[2]);
3319f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  LoadTexture();
3329f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3339f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glActiveTexture(GL_TEXTURE0);
3349f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindTexture(GL_TEXTURE_2D, compositing_textures_[3]);
3359f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  UpdateTexture();
3369f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  LoadTexture();
3379f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3389f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glActiveTexture(GL_TEXTURE0);
3399f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glBindTexture(GL_TEXTURE_2D, compositing_textures_[4]);
3409f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  UpdateTexture();
3419f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  LoadTexture();
3429f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3439f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Set up vertex & fragment shaders.
3449f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  compositing_background_program_ =
3459f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev      TripleTextureBlendShaderProgram(vbo_vertex,
3469f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev                                      vbo_texture, vbo_texture, vbo_texture);
3479f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  compositing_foreground_program_ =
3489f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev      BasicTextureShaderProgram(vbo_vertex, vbo_texture);
3499f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  if (!compositing_background_program_ || !compositing_foreground_program_) {
3508faad30e5a44271d9e50c4d75e1271018d7439b5Ilja H. Friedel    printf("# Warning: Could not set up compositing shader.\n");
3519f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  }
3529f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
3539f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3549f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevvoid WindowManagerCompositingTest::TeardownCompositing() {
3559f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDeleteProgram(compositing_background_program_);
3569f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glDeleteProgram(compositing_foreground_program_);
3579f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
3589f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3599f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevvoid WindowManagerCompositingTest::InitBaseTexture() {
3609f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  for (int y = 0; y < WINDOW_HEIGHT; y++) {
3619f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    for (int x = 0; x < WINDOW_WIDTH; x++) {
3629f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev      // This color is gray, half alpha.
3639f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev      texture_base_[y*WINDOW_WIDTH+x] = 0x80808080;
3649f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev    }
3659f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  }
3669f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
3679f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3689f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// UpdateTexture simulates Chrome updating tab contents.
3699f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// We cause a bunch of read and write cpu memory bandwidth.
3709f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev// It's a very rough approximation.
3719f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevvoid WindowManagerCompositingTest::UpdateTexture() {
3729f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  memcpy(texture_update_, texture_base_, sizeof(texture_base_));
3739f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
3749f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3759f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichevvoid WindowManagerCompositingTest::LoadTexture() {
3769f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  // Use GL_RGBA for compatibility with GLES2.0.
3779f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
3789f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev               WINDOW_WIDTH, WINDOW_HEIGHT, 0,
3799f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev               GL_RGBA, GL_UNSIGNED_BYTE, texture_update_);
3809f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev}
3819f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev
3829f9b873ae65c0a087ed3cd9856121a6d41e3410aAlexey Marinichev} // namespace glbench
383