15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/types.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gl_utils.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define SHADER0(src) \
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#ifdef GL_ES\n"\
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "precision mediump float;\n"\
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#endif\n"\
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    #src
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define SHADER(src) { false, SHADER0(src), }
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define SHADER_EXTERNAL_OES0(src) \
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "#extension GL_OES_EGL_image_external : require\n"\
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "#ifdef GL_ES\n"\
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "precision mediump float;\n"\
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "#endif\n"\
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    #src
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define SHADER_EXTERNAL_OES(src) { true, SHADER_EXTERNAL_OES0(src), }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLfloat kQuadVertices[] = { -1.0f, -1.0f, 0.0f, 1.0f,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   1.0f, -1.0f, 0.0f, 1.0f,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   1.0f,  1.0f, 0.0f, 1.0f,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  -1.0f,  1.0f, 0.0f, 1.0f };
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ProgramId {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROGRAM_COPY_TEXTURE,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROGRAM_COPY_TEXTURE_FLIP_Y,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY,
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY,
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PROGRAM_COPY_TEXTURE_OES,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PROGRAM_COPY_TEXTURE_OES_FLIP_Y,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ShaderInfo {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_egl_image_external;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* source;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const ShaderInfo shader_infos[] = {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VERTEX_SHADER_POS_TEX
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uniform mat4 u_matrix;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    attribute vec4 a_position;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gl_Position = u_matrix * a_position;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_FLIP_Y
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor.rgb *= gl_FragColor.a;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gl_FragColor.a > 0.0)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor.rgb /= gl_FragColor.a;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor.rgb *= gl_FragColor.a;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gl_FragColor.a > 0.0)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor.rgb /= gl_FragColor.a;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    precision mediump float;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform samplerExternalOES u_texSampler;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_FLIP_Y
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     precision mediump float;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     uniform samplerExternalOES u_texSampler;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     varying vec2 v_uv;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     void main(void) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       gl_FragColor =
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     }),
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     precision mediump float;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     uniform samplerExternalOES u_texSampler;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     varying vec2 v_uv;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     void main(void) {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       gl_FragColor = texture2D(u_texSampler, v_uv.st);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       gl_FragColor.rgb *= gl_FragColor.a;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     }),
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    precision mediump float;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform samplerExternalOES u_texSampler;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gl_FragColor.a > 0.0)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor.rgb /= gl_FragColor.a;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA_FLIP_Y
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      precision mediump float;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uniform samplerExternalOES u_texSampler;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      varying vec2 v_uv;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      void main(void) {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor =
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor.rgb *= gl_FragColor.a;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }),
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA_FLIP_Y
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      precision mediump float;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uniform samplerExternalOES u_texSampler;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      varying vec2 v_uv;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      void main(void) {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor =
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (gl_FragColor.a > 0.0)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gl_FragColor.rgb /= gl_FragColor.a;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }),
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNumShaders = arraysize(shader_infos);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the correct program to evaluate the copy operation for
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the CHROMIUM_flipy and premultiply alpha pixel store settings.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProgramId GetProgram(
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool flip_y,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool premultiply_alpha,
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool unpremultiply_alpha,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_source_external_oes) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If both pre-multiply and unpremultiply are requested, then perform no
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // alpha manipulation.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (premultiply_alpha && unpremultiply_alpha) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    premultiply_alpha = false;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unpremultiply_alpha = false;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // bit 0: Flip_y
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // bit 1: Premult
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // bit 2: Unpremult
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // bit 3: External_oes
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static ProgramId program_ids[] = {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_FLIP_Y,                         // F
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA,              //   P
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY,        // F P
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA,            //     U
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY,      // F   U
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE,                                //   P U
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE,                                // F P U
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES,                            //       E
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_FLIP_Y,                     // F     E
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA,          //   P   E
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY,    // F P   E
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA,        //     U E
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY,  // F   U E
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES,                            //   P U E
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES,                            // F P U E
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned index = (flip_y                 ? (1 << 0) : 0) |
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   (premultiply_alpha      ? (1 << 1) : 0) |
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   (unpremultiply_alpha    ? (1 << 2) : 0) |
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   (is_source_external_oes ? (1 << 3) : 0);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return program_ids[index];
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gpu {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager()
222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  : initialized_(false),
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    buffer_id_(0),
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    framebuffer_(0) {
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (int i = 0; i < kNumPrograms; ++i) {
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    programs_[i] = 0;
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    matrix_handle_[i] = 0;
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    sampler_locations_[i] = 0;
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CopyTextureCHROMIUMResourceManager::Initialize(
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gles2::GLES2Decoder* decoder) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kVertexPositionAttrib == 0u,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Position_attribs_must_be_0);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* extensions =
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool have_egl_image_external = extensions &&
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      strstr(extensions, "GL_OES_EGL_image_external");
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize all of the GPU resources required to perform the copy.
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glGenBuffersARB(1, &buffer_id_);
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               GL_STATIC_DRAW);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGenFramebuffersEXT(1, &framebuffer_);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gman): Init these on demand.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint shaders[kNumShaders];
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int shader = 0; shader < kNumShaders; ++shader) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shaders[shader] = glCreateShader(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShaderInfo& info = shader_infos[shader];
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (info.needs_egl_image_external && !have_egl_image_external) {
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* shader_source = shader_infos[shader].source;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glShaderSource(shaders[shader], 1, &shader_source, 0);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glCompileShader(shaders[shader]);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint compile_status;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (GL_TRUE != compile_status)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure.";
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gman): Init these on demand.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int program = 0; program < kNumPrograms; ++program) {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShaderInfo& info = shader_infos[program + 1];
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (info.needs_egl_image_external && !have_egl_image_external) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    programs_[program] = glCreateProgram();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glAttachShader(programs_[program], shaders[0]);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glAttachShader(programs_[program], shaders[program + 1]);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindAttribLocation(programs_[program], kVertexPositionAttrib,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         "a_position");
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glLinkProgram(programs_[program]);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint linked;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!linked)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure.";
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sampler_locations_[program] = glGetUniformLocation(programs_[program],
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      "u_texSampler");
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    matrix_handle_[program] = glGetUniformLocation(programs_[program],
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                   "u_matrix");
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int shader = 0; shader < kNumShaders; ++shader)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glDeleteShader(shaders[shader]);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreBufferBindings();
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initialized_ = true;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyTextureCHROMIUMResourceManager::Destroy() {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!initialized_)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glDeleteFramebuffersEXT(1, &framebuffer_);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (int program = 0; program < kNumPrograms; ++program) {
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (programs_[program])
315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      glDeleteProgram(programs_[program]);
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glDeleteBuffersARB(1, &buffer_id_);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gles2::GLES2Decoder* decoder,
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLenum source_target,
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLenum dest_target,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint source_id,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint dest_id,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLsizei width,
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLsizei height,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool flip_y,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool premultiply_alpha,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool unpremultiply_alpha) {
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Use default transform matrix if no transform passed in.
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             0.0f, 1.0f, 0.0f, 0.0f,
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             0.0f, 0.0f, 1.0f, 0.0f,
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             0.0f, 0.0f, 0.0f, 1.0f};
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DoCopyTextureWithTransform(decoder, source_target, dest_target, source_id,
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dest_id, level, width, height, flip_y, premultiply_alpha,
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      unpremultiply_alpha, default_matrix);
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const gles2::GLES2Decoder* decoder,
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLenum source_target,
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLenum dest_target,
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLuint source_id,
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLuint dest_id,
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLint level,
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLsizei width,
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLsizei height,
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool flip_y,
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool premultiply_alpha,
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool unpremultiply_alpha,
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GLfloat transform_matrix[16]) {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(source_target == GL_TEXTURE_2D ||
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         source_target == GL_TEXTURE_EXTERNAL_OES);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!initialized_) {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLuint program = GetProgram(
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flip_y, premultiply_alpha, unpremultiply_alpha,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      source_target == GL_TEXTURE_EXTERNAL_OES);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glUseProgram(programs_[program]);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glValidateProgram(programs_[program]);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint validation_status;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GL_TRUE != validation_status) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader.";
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  glUniformMatrix4fv(matrix_handle_[program], 1, GL_FALSE, transform_matrix);
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glActiveTexture(GL_TEXTURE0);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glBindTexture(GL_TEXTURE_2D, dest_id);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NVidia drivers require texture settings to be a certain way
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or they won't report FRAMEBUFFER_COMPLETE.
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            dest_id, level);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GL_FRAMEBUFFER_COMPLETE != fb_status) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer.";
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glEnableVertexAttribArray(kVertexPositionAttrib);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE,
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          4 * sizeof(GLfloat), 0);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glUniform1i(sampler_locations_[program], 0);
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glBindTexture(source_target, source_id);
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_DEPTH_TEST);
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_SCISSOR_TEST);
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_STENCIL_TEST);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_CULL_FACE);
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDepthMask(GL_FALSE);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_BLEND);
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glViewport(0, 0, width, height);
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreAttribute(kVertexPositionAttrib);
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreTextureState(source_id);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreTextureState(dest_id);
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  decoder->RestoreTextureUnitBindings(0);
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreActiveTexture();
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreProgramBindings();
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreBufferBindings();
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreFramebufferBindings();
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreGlobalState();
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
437