Update from https://crrev.com/317530

TBR=qsr@chromium.org
BUG=461092

Review URL: https://codereview.chromium.org/952893003
diff --git a/gpu/perftests/texture_upload_perftest.cc b/gpu/perftests/texture_upload_perftest.cc
index f691c9e..2e9ef6c 100644
--- a/gpu/perftests/texture_upload_perftest.cc
+++ b/gpu/perftests/texture_upload_perftest.cc
@@ -6,8 +6,10 @@
 #include <vector>
 
 #include "base/containers/small_map.h"
+#include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "gpu/command_buffer/service/gpu_timing.h"
 #include "gpu/perftests/measurements.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/size.h"
@@ -31,7 +33,7 @@
   varying vec2 v_texCoord;
   void main() {
     gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);
-    v_texCoord = vec2((a_position.x + 1) * 0.5, (a_position.y + 1) * 0.5);
+    v_texCoord = vec2((a_position.x + 1.0) * 0.5, (a_position.y + 1.0) * 0.5);
   }
 );
 const char kFragmentShader[] =
@@ -96,12 +98,30 @@
   void SetUp() override {
     // Initialize an offscreen surface and a gl context.
     gfx::GLSurface::InitializeOneOff();
-    surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size_);
+    surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(4, 4));
     gl_context_ = gfx::GLContext::CreateGLContext(NULL,  // share_group
                                                   surface_.get(),
                                                   gfx::PreferIntegratedGpu);
-
     ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get());
+    glGenTextures(1, &color_texture_);
+    glBindTexture(GL_TEXTURE_2D, color_texture_);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), 0,
+                 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    glGenFramebuffersEXT(1, &framebuffer_object_);
+    glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_object_);
+
+    glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                              GL_TEXTURE_2D, color_texture_, 0);
+    DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+              glCheckFramebufferStatusEXT(GL_FRAMEBUFFER));
+
+    glViewport(0, 0, size_.width(), size_.height());
+
     if (gpu_timing_.Initialize(gl_context_.get())) {
       LOG(INFO) << "Gpu timing initialized with timer type: "
                 << gpu_timing_.GetTimerTypeName();
@@ -110,7 +130,6 @@
     } else {
       LOG(WARNING) << "Can't initialize gpu timing";
     }
-
     // Prepare a simple program and a vertex buffer that will be
     // used to draw a quad on the offscreen surface.
     vertex_shader_ = LoadShader(GL_VERTEX_SHADER, kVertexShader);
@@ -142,18 +161,14 @@
 
   void TearDown() override {
     ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get());
-    if (program_object_ != 0) {
-      glDeleteProgram(program_object_);
-    }
-    if (vertex_shader_ != 0) {
-      glDeleteShader(vertex_shader_);
-    }
-    if (fragment_shader_ != 0) {
-      glDeleteShader(fragment_shader_);
-    }
-    if (vertex_buffer_ != 0) {
-      glDeleteShader(vertex_buffer_);
-    }
+    glDeleteProgram(program_object_);
+    glDeleteShader(vertex_shader_);
+    glDeleteShader(fragment_shader_);
+    glDeleteShader(vertex_buffer_);
+
+    glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
+    glDeleteFramebuffersEXT(1, &framebuffer_object_);
+    glDeleteTextures(1, &color_texture_);
 
     gl_context_ = nullptr;
     surface_ = nullptr;
@@ -167,6 +182,8 @@
                                          const GLenum format,
                                          const GLenum type) {
     ui::ScopedMakeCurrent smc(gl_context_.get(), surface_.get());
+    DCHECK_NE(0u, framebuffer_object_);
+    glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_object_);
 
     MeasurementTimers total_timers(&gpu_timing_);
     GLuint texture_id = 0;
@@ -178,8 +195,8 @@
 
     glTexImage2D(GL_TEXTURE_2D, 0, format, size_.width(), size_.height(), 0,
                  format, type, &pixels[0]);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     CheckNoGlError();
@@ -222,11 +239,13 @@
     return measurements;
   }
 
-  const gfx::Size size_;  // for the offscreen surface and the texture
+  const gfx::Size size_;  // for the fbo and the texture
   scoped_refptr<gfx::GLContext> gl_context_;
   scoped_refptr<gfx::GLSurface> surface_;
   GPUTiming gpu_timing_;
 
+  GLuint color_texture_ = 0;
+  GLuint framebuffer_object_ = 0;
   GLuint vertex_shader_ = 0;
   GLuint fragment_shader_ = 0;
   GLuint program_object_ = 0;