gles2_cmd_copy_texture_chromium.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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(
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    attribute vec4 a_position;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_Position = a_position;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_FLIP_Y
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor.rgb *= gl_FragColor.a;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gl_FragColor.a > 0.0)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor.rgb /= gl_FragColor.a;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor.rgb *= gl_FragColor.a;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER(
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform sampler2D u_texSampler;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gl_FragColor.a > 0.0)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor.rgb /= gl_FragColor.a;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    precision mediump float;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform samplerExternalOES u_texSampler;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_FLIP_Y
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     precision mediump float;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     uniform samplerExternalOES u_texSampler;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     varying vec2 v_uv;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     void main(void) {
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       gl_FragColor =
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     }),
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     precision mediump float;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     uniform samplerExternalOES u_texSampler;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     varying vec2 v_uv;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     void main(void) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       gl_FragColor = texture2D(u_texSampler, v_uv.st);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       gl_FragColor.rgb *= gl_FragColor.a;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     }),
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    precision mediump float;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uniform samplerExternalOES u_texSampler;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    varying vec2 v_uv;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void main(void) {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_FragColor = texture2D(u_texSampler, v_uv.st);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gl_FragColor.a > 0.0)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor.rgb /= gl_FragColor.a;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }),
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA_FLIP_Y
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      precision mediump float;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uniform samplerExternalOES u_texSampler;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      varying vec2 v_uv;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      void main(void) {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor =
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor.rgb *= gl_FragColor.a;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }),
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA_FLIP_Y
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SHADER_EXTERNAL_OES(
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      precision mediump float;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uniform samplerExternalOES u_texSampler;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      varying vec2 v_uv;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      void main(void) {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gl_FragColor =
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t));
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (gl_FragColor.a > 0.0)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gl_FragColor.rgb /= gl_FragColor.a;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }),
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNumShaders = arraysize(shader_infos);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the correct program to evaluate the copy operation for
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the CHROMIUM_flipy and premultiply alpha pixel store settings.
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProgramId GetProgram(
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool flip_y,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool premultiply_alpha,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool unpremultiply_alpha,
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_source_external_oes) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If both pre-multiply and unpremultiply are requested, then perform no
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // alpha manipulation.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (premultiply_alpha && unpremultiply_alpha) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    premultiply_alpha = false;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unpremultiply_alpha = false;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // bit 0: Flip_y
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // bit 1: Premult
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // bit 2: Unpremult
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // bit 3: External_oes
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static ProgramId program_ids[] = {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE,
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_FLIP_Y,                         // F
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA,              //   P
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY,        // F P
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA,            //     U
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY,      // F   U
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE,                                //   P U
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE,                                // F P U
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES,                            //       E
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_FLIP_Y,                     // F     E
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA,          //   P   E
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY,    // F P   E
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA,        //     U E
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY,  // F   U E
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES,                            //   P U E
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PROGRAM_COPY_TEXTURE_OES,                            // F P U E
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned index = (flip_y                 ? (1 << 0) : 0) |
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   (premultiply_alpha      ? (1 << 1) : 0) |
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   (unpremultiply_alpha    ? (1 << 2) : 0) |
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   (is_source_external_oes ? (1 << 3) : 0);
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return program_ids[index];
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gpu {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CopyTextureCHROMIUMResourceManager::Initialize(
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gles2::GLES2Decoder* decoder) {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kVertexPositionAttrib == 0u,
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Position_attribs_must_be_0);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* extensions =
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool have_egl_image_external = extensions &&
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      strstr(extensions, "GL_OES_EGL_image_external");
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize all of the GPU resources required to perform the copy.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glGenBuffersARB(1, &buffer_id_);
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               GL_STATIC_DRAW);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGenFramebuffersEXT(1, &framebuffer_);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gman): Init these on demand.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint shaders[kNumShaders];
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int shader = 0; shader < kNumShaders; ++shader) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shaders[shader] = glCreateShader(
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShaderInfo& info = shader_infos[shader];
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (info.needs_egl_image_external && !have_egl_image_external) {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* shader_source = shader_infos[shader].source;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glShaderSource(shaders[shader], 1, &shader_source, 0);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glCompileShader(shaders[shader]);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint compile_status;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (GL_TRUE != compile_status)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure.";
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gman): Init these on demand.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int program = 0; program < kNumPrograms; ++program) {
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShaderInfo& info = shader_infos[program + 1];
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (info.needs_egl_image_external && !have_egl_image_external) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    programs_[program] = glCreateProgram();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glAttachShader(programs_[program], shaders[0]);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glAttachShader(programs_[program], shaders[program + 1]);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindAttribLocation(programs_[program], kVertexPositionAttrib,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         "a_position");
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glLinkProgram(programs_[program]);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint linked;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!linked)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure.";
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sampler_locations_[program] = glGetUniformLocation(programs_[program],
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      "u_texSampler");
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int shader = 0; shader < kNumShaders; ++shader)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glDeleteShader(shaders[shader]);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreBufferBindings();
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initialized_ = true;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyTextureCHROMIUMResourceManager::Destroy() {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!initialized_)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glDeleteFramebuffersEXT(1, &framebuffer_);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int program = 0; program < kNumPrograms; ++program)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glDeleteProgram(programs_[program]);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glDeleteBuffersARB(1, &buffer_id_);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gles2::GLES2Decoder* decoder,
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLenum source_target,
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLenum dest_target,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint source_id,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint dest_id,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLsizei width,
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLsizei height,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool flip_y,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool premultiply_alpha,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool unpremultiply_alpha) {
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(source_target == GL_TEXTURE_2D ||
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         source_target == GL_TEXTURE_EXTERNAL_OES);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!initialized_) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLuint program = GetProgram(
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flip_y, premultiply_alpha, unpremultiply_alpha,
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      source_target == GL_TEXTURE_EXTERNAL_OES);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glUseProgram(programs_[program]);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glValidateProgram(programs_[program]);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint validation_status;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GL_TRUE != validation_status) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader.";
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glActiveTexture(GL_TEXTURE0);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glBindTexture(GL_TEXTURE_2D, dest_id);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NVidia drivers require texture settings to be a certain way
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or they won't report FRAMEBUFFER_COMPLETE.
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_);
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            dest_id, level);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GL_FRAMEBUFFER_COMPLETE != fb_status) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer.";
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glEnableVertexAttribArray(kVertexPositionAttrib);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE,
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          4 * sizeof(GLfloat), 0);
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glUniform1i(sampler_locations_[program], 0);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glBindTexture(source_target, source_id);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_DEPTH_TEST);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_SCISSOR_TEST);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_STENCIL_TEST);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_CULL_FACE);
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDepthMask(GL_FALSE);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDisable(GL_BLEND);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glViewport(0, 0, width, height);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreAttribute(kVertexPositionAttrib);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreTextureUnitBindings(0);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreTextureState(source_id);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreTextureState(dest_id);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreActiveTexture();
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreProgramBindings();
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreBufferBindings();
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreFramebufferBindings();
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder->RestoreGlobalState();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
396