1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/base/yuv_convert.h" 6 #include "media/tools/shader_bench/cpu_color_painter.h" 7 8 enum { kNumRGBPlanes = 1 }; 9 10 // Pass-through vertex shader. 11 static const char kVertexShader[] = 12 "precision highp float;\n" 13 "precision highp int;\n" 14 "varying vec2 interp_tc;\n" 15 "\n" 16 "attribute vec4 in_pos;\n" 17 "attribute vec2 in_tc;\n" 18 "\n" 19 "void main() {\n" 20 " interp_tc = in_tc;\n" 21 " gl_Position = in_pos;\n" 22 "}\n"; 23 24 // RGB pixel shader. 25 static const char kFragmentShader[] = 26 "precision mediump float;\n" 27 "precision mediump int;\n" 28 "varying vec2 interp_tc;\n" 29 "\n" 30 "uniform sampler2D rgba_tex;\n" 31 "\n" 32 "void main() {\n" 33 " vec4 texColor = texture2D(rgba_tex, interp_tc);" 34 " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w);\n" 35 "}\n"; 36 37 CPUColorPainter::CPUColorPainter() 38 : program_id_(-1) { 39 } 40 41 CPUColorPainter::~CPUColorPainter() { 42 if (program_id_) { 43 glDeleteProgram(program_id_); 44 glDeleteTextures(kNumRGBPlanes, textures_); 45 } 46 } 47 48 void CPUColorPainter::Initialize(int width, int height) { 49 glGenTextures(kNumRGBPlanes, textures_); 50 glActiveTexture(GL_TEXTURE0); 51 glBindTexture(GL_TEXTURE_2D, textures_[0]); 52 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 53 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 54 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 55 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 56 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 57 GL_RGBA, GL_UNSIGNED_BYTE, 0); 58 59 GLuint program = CreateShaderProgram(kVertexShader, kFragmentShader); 60 61 // Bind parameters. 62 glUniform1i(glGetUniformLocation(program, "rgba_tex"), 0); 63 program_id_ = program; 64 } 65 66 void CPUColorPainter::Paint(scoped_refptr<media::VideoFrame> video_frame) { 67 // Convert to RGB32 frame. 68 scoped_refptr<media::VideoFrame> rgba_frame = 69 media::VideoFrame::CreateFrame(media::VideoFrame::RGB32, 70 video_frame->coded_size(), 71 video_frame->visible_rect(), 72 video_frame->natural_size(), 73 base::TimeDelta()); 74 75 media::ConvertYUVToRGB32(video_frame->data(media::VideoFrame::kYPlane), 76 video_frame->data(media::VideoFrame::kUPlane), 77 video_frame->data(media::VideoFrame::kVPlane), 78 rgba_frame->data(0), 79 video_frame->coded_size().width(), 80 video_frame->coded_size().height(), 81 video_frame->stride(media::VideoFrame::kYPlane), 82 video_frame->stride(media::VideoFrame::kUPlane), 83 rgba_frame->stride(0), 84 media::YV12); 85 86 glBindTexture(GL_TEXTURE_2D, textures_[0]); 87 // Not accounting for x/y offset presently. 88 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 89 rgba_frame->visible_rect().width(), 90 rgba_frame->visible_rect().height(), 91 GL_RGBA, GL_UNSIGNED_BYTE, 92 rgba_frame->data(0)); 93 94 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 95 surface()->SwapBuffers(); 96 } 97