| Index: cc/gl_renderer.cc
|
| diff --git a/cc/gl_renderer.cc b/cc/gl_renderer.cc
|
| index 94f8d83124f945b5118af3f5b1d07a7bbcdc5fba..c2646c10451fe72cb824a03a96b00cd79c142369 100644
|
| --- a/cc/gl_renderer.cc
|
| +++ b/cc/gl_renderer.cc
|
| @@ -241,8 +241,10 @@ void GLRenderer::beginDrawingFrame(DrawingFrame& frame)
|
| GLC(m_context, m_context->disable(GL_CULL_FACE));
|
| GLC(m_context, m_context->colorMask(true, true, true, true));
|
| GLC(m_context, m_context->enable(GL_BLEND));
|
| + m_blendShadow = true;
|
| GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
| GLC(context(), context()->activeTexture(GL_TEXTURE0));
|
| + m_programShadow = 0;
|
| }
|
|
|
| void GLRenderer::doNoOp()
|
| @@ -254,11 +256,10 @@ void GLRenderer::doNoOp()
|
| void GLRenderer::drawQuad(DrawingFrame& frame, const DrawQuad* quad)
|
| {
|
| DCHECK(quad->rect.Contains(quad->visible_rect));
|
| -
|
| - if (quad->ShouldDrawWithBlending())
|
| - GLC(m_context, m_context->enable(GL_BLEND));
|
| - else
|
| - GLC(m_context, m_context->disable(GL_BLEND));
|
| + if (quad->material != DrawQuad::TEXTURE_CONTENT) {
|
| + flushTextureQuadCache();
|
| + setBlendEnabled(quad->ShouldDrawWithBlending());
|
| + }
|
|
|
| switch (quad->material) {
|
| case DrawQuad::INVALID:
|
| @@ -283,7 +284,7 @@ void GLRenderer::drawQuad(DrawingFrame& frame, const DrawQuad* quad)
|
| drawStreamVideoQuad(frame, StreamVideoDrawQuad::MaterialCast(quad));
|
| break;
|
| case DrawQuad::TEXTURE_CONTENT:
|
| - drawTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
|
| + enqueueTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
|
| break;
|
| case DrawQuad::TILED_CONTENT:
|
| drawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
|
| @@ -298,7 +299,7 @@ void GLRenderer::drawCheckerboardQuad(const DrawingFrame& frame, const Checkerbo
|
| {
|
| const TileCheckerboardProgram* program = tileCheckerboardProgram();
|
| DCHECK(program && (program->initialized() || isContextLost()));
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
|
|
| SkColor color = quad->color;
|
| GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation(), SkColorGetR(color) / 255.0, SkColorGetG(color) / 255.0, SkColorGetB(color) / 255.0, 1));
|
| @@ -324,7 +325,7 @@ void GLRenderer::drawDebugBorderQuad(const DrawingFrame& frame, const DebugBorde
|
| static float glMatrix[16];
|
| const SolidColorProgram* program = solidColorProgram();
|
| DCHECK(program && (program->initialized() || isContextLost()));
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
|
|
| // Use the full quadRect for debug quads to not move the edges based on partial swaps.
|
| const gfx::Rect& layerRect = quad->rect;
|
| @@ -342,7 +343,7 @@ void GLRenderer::drawDebugBorderQuad(const DrawingFrame& frame, const DebugBorde
|
| GLC(context(), context()->lineWidth(quad->width));
|
|
|
| // The indices for the line are stored in the same array as the triangle indices.
|
| - GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 6 * sizeof(unsigned short)));
|
| + GLC(context(), context()->drawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0));
|
| }
|
|
|
| static WebGraphicsContext3D* getFilterContext(bool hasImplThread)
|
| @@ -587,7 +588,7 @@ void GLRenderer::drawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQua
|
| int shaderAlphaLocation = -1;
|
| if (useAA && maskTextureId) {
|
| const RenderPassMaskProgramAA* program = renderPassMaskProgramAA();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
| GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
|
|
| shaderQuadLocation = program->vertexShader().pointLocation();
|
| @@ -599,7 +600,7 @@ void GLRenderer::drawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQua
|
| shaderAlphaLocation = program->fragmentShader().alphaLocation();
|
| } else if (!useAA && maskTextureId) {
|
| const RenderPassMaskProgram* program = renderPassMaskProgram();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
| GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
|
|
| shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocation();
|
| @@ -609,7 +610,7 @@ void GLRenderer::drawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQua
|
| shaderAlphaLocation = program->fragmentShader().alphaLocation();
|
| } else if (useAA && !maskTextureId) {
|
| const RenderPassProgramAA* program = renderPassProgramAA();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
| GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
|
|
| shaderQuadLocation = program->vertexShader().pointLocation();
|
| @@ -618,7 +619,7 @@ void GLRenderer::drawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQua
|
| shaderAlphaLocation = program->fragmentShader().alphaLocation();
|
| } else {
|
| const RenderPassProgram* program = renderPassProgram();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
| GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
|
|
| shaderMatrixLocation = program->vertexShader().matrixLocation();
|
| @@ -660,7 +661,7 @@ void GLRenderer::drawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQua
|
| void GLRenderer::drawSolidColorQuad(const DrawingFrame& frame, const SolidColorDrawQuad* quad)
|
| {
|
| const SolidColorProgram* program = solidColorProgram();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
|
|
| SkColor color = quad->color;
|
| float opacity = quad->opacity();
|
| @@ -778,7 +779,7 @@ void GLRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQuad* qua
|
| }
|
| }
|
|
|
| - GLC(context(), context()->useProgram(uniforms.program));
|
| + setUseProgram(uniforms.program);
|
| GLC(context(), context()->uniform1i(uniforms.samplerLocation, 0));
|
| ResourceProvider::ScopedReadLockGL quadResourceLock(m_resourceProvider, quad->resource_id);
|
| GLC(context(), context()->bindTexture(GL_TEXTURE_2D, quadResourceLock.textureId()));
|
| @@ -895,7 +896,7 @@ void GLRenderer::drawYUVVideoQuad(const DrawingFrame& frame, const YUVVideoDrawQ
|
| GLC(context(), context()->activeTexture(GL_TEXTURE3));
|
| GLC(context(), context()->bindTexture(GL_TEXTURE_2D, vPlaneLock.textureId()));
|
|
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
|
|
| GLC(context(), context()->uniform2f(program->vertexShader().texScaleLocation(), quad->tex_scale.width(), quad->tex_scale.height()));
|
| GLC(context(), context()->uniform1i(program->fragmentShader().yTextureLocation(), 1));
|
| @@ -938,7 +939,7 @@ void GLRenderer::drawStreamVideoQuad(const DrawingFrame& frame, const StreamVide
|
| DCHECK(m_capabilities.usingEglImage);
|
|
|
| const VideoStreamTextureProgram* program = videoStreamTextureProgram();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
|
|
| toGLMatrix(&glMatrix[0], quad->matrix);
|
| GLC(context(), context()->uniformMatrix4fv(program->vertexShader().texMatrixLocation(), 1, false, glMatrix));
|
| @@ -977,6 +978,102 @@ struct TexTransformTextureProgramBinding : TextureProgramBinding {
|
| int texTransformLocation;
|
| };
|
|
|
| +void GLRenderer::flushTextureQuadCache()
|
| +{
|
| + // Check to see if we have anything to draw.
|
| + if (m_drawCache.program_id == 0)
|
| + return;
|
| +
|
| + // Set the correct blending mode.
|
| + setBlendEnabled(m_drawCache.needs_blending);
|
| +
|
| + // Bind the program to the GL state.
|
| + setUseProgram(m_drawCache.program_id);
|
| +
|
| + // Assume the current active textures is 0.
|
| + ResourceProvider::ScopedReadLockGL lockedQuad(m_resourceProvider, m_drawCache.resource_id);
|
| + GLC(context(), context()->bindTexture(GL_TEXTURE_2D, lockedQuad.textureId()));
|
| +
|
| + // set up premultiplied alpha.
|
| + if (!m_drawCache.use_premultiplied_alpha) {
|
| + // As it turns out, the premultiplied alpha blending function (ONE, ONE_MINUS_SRC_ALPHA)
|
| + // will never cause the alpha channel to be set to anything less than 1.0 if it is
|
| + // initialized to that value! Therefore, premultipliedAlpha being false is the first
|
| + // situation we can generally see an alpha channel less than 1.0 coming out of the
|
| + // compositor. This is causing platform differences in some layout tests (see
|
| + // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation, use a separate
|
| + // blend function for the alpha channel to avoid modifying it. Don't use colorMask for this
|
| + // as it has performance implications on some platforms.
|
| + GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE));
|
| + }
|
| +
|
| + // Set the shader opacity.
|
| + setShaderOpacity(m_drawCache.alpha, m_drawCache.alpha_location);
|
| +
|
| + COMPILE_ASSERT(sizeof(Float4) == 4 * sizeof(float), struct_is_densely_packed);
|
| + COMPILE_ASSERT(sizeof(Float16) == 16 * sizeof(float), struct_is_densely_packed);
|
| +
|
| + // Upload the tranforms for both points and uvs.
|
| + GLC(m_context, m_context->uniformMatrix4fv((int)m_drawCache.matrix_location, (int)m_drawCache.matrix_data.size(), false, (float*)&m_drawCache.matrix_data.front()));
|
| + GLC(m_context, m_context->uniform4fv((int)m_drawCache.uv_xform_location, (int)m_drawCache.uv_xform_data.size(), (float*)&m_drawCache.uv_xform_data.front()));
|
| +
|
| + // Draw the quads!
|
| + GLC(m_context, m_context->drawElements(GL_TRIANGLES, 6 * m_drawCache.matrix_data.size(), GL_UNSIGNED_SHORT, 0));
|
| +
|
| + // Clean up after ourselves (reset state set above).
|
| + if (!m_drawCache.use_premultiplied_alpha)
|
| + GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
| +
|
| + // Clear the cache.
|
| + m_drawCache.program_id = 0;
|
| + m_drawCache.uv_xform_data.resize(0);
|
| + m_drawCache.matrix_data.resize(0);
|
| +}
|
| +
|
| +void GLRenderer::enqueueTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* quad)
|
| +{
|
| + // Choose the correcte texture program binding
|
| + TexTransformTextureProgramBinding binding;
|
| + if (quad->flipped)
|
| + binding.set(textureProgramFlip(), context());
|
| + else
|
| + binding.set(textureProgram(), context());
|
| +
|
| + int resourceID = quad->resource_id;
|
| +
|
| + if (m_drawCache.program_id != binding.programId ||
|
| + m_drawCache.resource_id != resourceID ||
|
| + m_drawCache.alpha != quad->opacity() ||
|
| + m_drawCache.use_premultiplied_alpha != quad->premultiplied_alpha ||
|
| + m_drawCache.needs_blending != quad->ShouldDrawWithBlending() ||
|
| + m_drawCache.matrix_data.size() >= 8) {
|
| + flushTextureQuadCache();
|
| + m_drawCache.program_id = binding.programId;
|
| + m_drawCache.resource_id = resourceID;
|
| + m_drawCache.alpha = quad->opacity();
|
| + m_drawCache.use_premultiplied_alpha = quad->premultiplied_alpha;
|
| + m_drawCache.needs_blending = quad->ShouldDrawWithBlending();
|
| +
|
| + m_drawCache.alpha_location = binding.alphaLocation;
|
| + m_drawCache.uv_xform_location = binding.texTransformLocation;
|
| + m_drawCache.matrix_location = binding.matrixLocation;
|
| + }
|
| +
|
| + // Generate the uv-transform
|
| + const gfx::RectF& uvRect = quad->uv_rect;
|
| + Float4 uv = {uvRect.x(), uvRect.y(), uvRect.width(), uvRect.height()};
|
| + m_drawCache.uv_xform_data.push_back(uv);
|
| +
|
| + // Generate the transform matrix
|
| + gfx::Transform quadRectMatrix;
|
| + quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect);
|
| + quadRectMatrix = frame.projectionMatrix * quadRectMatrix;
|
| +
|
| + Float16 m;
|
| + quadRectMatrix.matrix().asColMajorf(m.data);
|
| + m_drawCache.matrix_data.push_back(m);
|
| +}
|
| +
|
| void GLRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQuad* quad)
|
| {
|
| TexTransformTextureProgramBinding binding;
|
| @@ -984,7 +1081,7 @@ void GLRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQua
|
| binding.set(textureProgramFlip(), context());
|
| else
|
| binding.set(textureProgram(), context());
|
| - GLC(context(), context()->useProgram(binding.programId));
|
| + setUseProgram(binding.programId);
|
| GLC(context(), context()->uniform1i(binding.samplerLocation, 0));
|
| const gfx::RectF& uvRect = quad->uv_rect;
|
| GLC(context(), context()->uniform4f(binding.texTransformLocation, uvRect.x(), uvRect.y(), uvRect.width(), uvRect.height()));
|
| @@ -1016,7 +1113,7 @@ void GLRenderer::drawIOSurfaceQuad(const DrawingFrame& frame, const IOSurfaceDra
|
| TexTransformTextureProgramBinding binding;
|
| binding.set(textureIOSurfaceProgram(), context());
|
|
|
| - GLC(context(), context()->useProgram(binding.programId));
|
| + setUseProgram(binding.programId);
|
| GLC(context(), context()->uniform1i(binding.samplerLocation, 0));
|
| if (quad->orientation == IOSurfaceDrawQuad::FLIPPED)
|
| GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, quad->io_surface_size.height(), quad->io_surface_size.width(), quad->io_surface_size.height() * -1.0));
|
| @@ -1037,6 +1134,12 @@ void GLRenderer::finishDrawingFrame(DrawingFrame& frame)
|
| m_swapBufferRect.Union(gfx::ToEnclosingRect(frame.rootDamageRect));
|
|
|
| GLC(m_context, m_context->disable(GL_BLEND));
|
| + m_blendShadow = false;
|
| +}
|
| +
|
| +void GLRenderer::finishDrawingQuadList()
|
| +{
|
| + flushTextureQuadCache();
|
| }
|
|
|
| bool GLRenderer::flippedFramebuffer() const
|
| @@ -1049,6 +1152,7 @@ void GLRenderer::ensureScissorTestEnabled()
|
| if (m_isScissorEnabled)
|
| return;
|
|
|
| + flushTextureQuadCache();
|
| GLC(m_context, m_context->enable(GL_SCISSOR_TEST));
|
| m_isScissorEnabled = true;
|
| }
|
| @@ -1058,6 +1162,7 @@ void GLRenderer::ensureScissorTestDisabled()
|
| if (!m_isScissorEnabled)
|
| return;
|
|
|
| + flushTextureQuadCache();
|
| GLC(m_context, m_context->disable(GL_SCISSOR_TEST));
|
| m_isScissorEnabled = false;
|
| }
|
| @@ -1090,6 +1195,26 @@ void GLRenderer::setShaderOpacity(float opacity, int alphaLocation)
|
| GLC(m_context, m_context->uniform1f(alphaLocation, opacity));
|
| }
|
|
|
| +void GLRenderer::setBlendEnabled(bool enabled)
|
| +{
|
| + if (enabled == m_blendShadow)
|
| + return;
|
| +
|
| + if (enabled)
|
| + GLC(m_context, m_context->enable(GL_BLEND));
|
| + else
|
| + GLC(m_context, m_context->disable(GL_BLEND));
|
| + m_blendShadow = enabled;
|
| +}
|
| +
|
| +void GLRenderer::setUseProgram(unsigned program)
|
| +{
|
| + if (program == m_programShadow)
|
| + return;
|
| + GLC(m_context, m_context->useProgram(program));
|
| + m_programShadow = program;
|
| +}
|
| +
|
| void GLRenderer::drawQuadGeometry(const DrawingFrame& frame, const gfx::Transform& drawTransform, const gfx::RectF& quadRect, int matrixLocation)
|
| {
|
| gfx::Transform quadRectMatrix;
|
| @@ -1107,7 +1232,7 @@ void GLRenderer::copyTextureToFramebuffer(const DrawingFrame& frame, int texture
|
|
|
| GLC(context(), context()->bindTexture(GL_TEXTURE_2D, textureId));
|
|
|
| - GLC(context(), context()->useProgram(program->program()));
|
| + setUseProgram(program->program());
|
| GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
| setShaderOpacity(1, program->fragmentShader().alphaLocation());
|
| drawQuadGeometry(frame, drawMatrix, rect, program->vertexShader().matrixLocation());
|
| @@ -1358,6 +1483,7 @@ void GLRenderer::setScissorTestRect(const gfx::Rect& scissorRect)
|
| return;
|
|
|
| m_scissorRect = scissorRect;
|
| + flushTextureQuadCache();
|
| GLC(m_context, m_context->scissor(scissorRect.x(), scissorRect.y(), scissorRect.width(), scissorRect.height()));
|
| }
|
|
|
| @@ -1527,6 +1653,7 @@ const GLRenderer::TextureProgram* GLRenderer::textureProgram()
|
| if (!m_textureProgram->initialized()) {
|
| TRACE_EVENT0("cc", "GLRenderer::textureProgram::initialize");
|
| m_textureProgram->initialize(m_context, m_isUsingBindUniform);
|
| + GLC(context(), context()->uniform1i(m_textureProgram.get()->fragmentShader().samplerLocation(), 0));
|
| }
|
| return m_textureProgram.get();
|
| }
|
| @@ -1538,6 +1665,7 @@ const GLRenderer::TextureProgramFlip* GLRenderer::textureProgramFlip()
|
| if (!m_textureProgramFlip->initialized()) {
|
| TRACE_EVENT0("cc", "GLRenderer::textureProgramFlip::initialize");
|
| m_textureProgramFlip->initialize(m_context, m_isUsingBindUniform);
|
| + GLC(context(), context()->uniform1i(m_textureProgramFlip.get()->fragmentShader().samplerLocation(), 0));
|
| }
|
| return m_textureProgramFlip.get();
|
| }
|
|
|