2 * Copyright 2010, The Android Open Source Project
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "ShaderProgram.h"
29 #if USE(ACCELERATED_COMPOSITING)
31 #include "FloatPoint3D.h"
33 #include "TilesManager.h"
35 #include <GLES2/gl2.h>
36 #include <GLES2/gl2ext.h>
37 #include <cutils/log.h>
38 #include <wtf/CurrentTime.h>
39 #include <wtf/text/CString.h>
42 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ShaderProgram", __VA_ARGS__)
46 static const char gVertexShader[] =
47 "attribute vec4 vPosition;\n"
48 "uniform mat4 projectionMatrix;\n"
49 "varying vec2 v_texCoord;\n"
51 " gl_Position = projectionMatrix * vPosition;\n"
52 " v_texCoord = vec2(vPosition);\n"
55 static const char gFragmentShader[] =
56 "precision mediump float;\n"
57 "varying vec2 v_texCoord; \n"
58 "uniform float alpha; \n"
59 "uniform sampler2D s_texture; \n"
61 " gl_FragColor = texture2D(s_texture, v_texCoord); \n"
62 " gl_FragColor *= alpha; "
65 static const char gFragmentShaderInverted[] =
66 "precision mediump float;\n"
67 "varying vec2 v_texCoord; \n"
68 "uniform float alpha; \n"
69 "uniform float contrast; \n"
70 "uniform sampler2D s_texture; \n"
72 " vec4 pixel = texture2D(s_texture, v_texCoord); \n"
73 " float a = pixel.a; \n"
74 " float color = a - (0.2989 * pixel.r + 0.5866 * pixel.g + 0.1145 * pixel.b);\n"
75 " color = ((color - a/2.0) * contrast) + a/2.0; \n"
76 " pixel.rgb = vec3(color, color, color); \n "
77 " gl_FragColor = pixel; \n"
78 " gl_FragColor *= alpha; \n"
81 static const char gVideoVertexShader[] =
82 "attribute vec4 vPosition;\n"
83 "uniform mat4 textureMatrix;\n"
84 "uniform mat4 projectionMatrix;\n"
85 "varying vec2 v_texCoord;\n"
87 " gl_Position = projectionMatrix * vPosition;\n"
88 " v_texCoord = vec2(textureMatrix * vec4(vPosition.x, 1.0 - vPosition.y, 0.0, 1.0));\n"
91 static const char gVideoFragmentShader[] =
92 "#extension GL_OES_EGL_image_external : require\n"
93 "precision mediump float;\n"
94 "uniform samplerExternalOES s_yuvTexture;\n"
95 "varying vec2 v_texCoord;\n"
97 " gl_FragColor = texture2D(s_yuvTexture, v_texCoord);\n"
100 static const char gSurfaceTextureOESFragmentShader[] =
101 "#extension GL_OES_EGL_image_external : require\n"
102 "precision mediump float;\n"
103 "varying vec2 v_texCoord; \n"
104 "uniform float alpha; \n"
105 "uniform samplerExternalOES s_texture; \n"
107 " gl_FragColor = texture2D(s_texture, v_texCoord); \n"
108 " gl_FragColor *= alpha; "
111 static const char gSurfaceTextureOESFragmentShaderInverted[] =
112 "#extension GL_OES_EGL_image_external : require\n"
113 "precision mediump float;\n"
114 "varying vec2 v_texCoord; \n"
115 "uniform float alpha; \n"
116 "uniform float contrast; \n"
117 "uniform samplerExternalOES s_texture; \n"
119 " vec4 pixel = texture2D(s_texture, v_texCoord); \n"
120 " float a = pixel.a; \n"
121 " float color = a - (0.2989 * pixel.r + 0.5866 * pixel.g + 0.1145 * pixel.b);\n"
122 " color = ((color - a/2.0) * contrast) + a/2.0; \n"
123 " pixel.rgb = vec3(color, color, color); \n "
124 " gl_FragColor = pixel; \n"
125 " gl_FragColor *= alpha; \n"
128 GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource)
130 GLuint shader = glCreateShader(shaderType);
132 glShaderSource(shader, 1, &pSource, 0);
133 glCompileShader(shader);
135 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
138 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
140 char* buf = (char*) malloc(infoLen);
142 glGetShaderInfoLog(shader, infoLen, 0, buf);
143 XLOG("could not compile shader %d:\n%s\n", shaderType, buf);
146 glDeleteShader(shader);
154 GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragmentSource)
156 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
158 XLOG("couldn't load the vertex shader!");
162 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
164 XLOG("couldn't load the pixel shader!");
168 GLuint program = glCreateProgram();
170 glAttachShader(program, vertexShader);
171 GLUtils::checkGlError("glAttachShader vertex");
172 glAttachShader(program, pixelShader);
173 GLUtils::checkGlError("glAttachShader pixel");
174 glLinkProgram(program);
175 GLint linkStatus = GL_FALSE;
176 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
177 if (linkStatus != GL_TRUE) {
179 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
181 char* buf = (char*) malloc(bufLength);
183 glGetProgramInfoLog(program, bufLength, 0, buf);
184 XLOG("could not link program:\n%s\n", buf);
188 glDeleteProgram(program);
195 ShaderProgram::ShaderProgram()
196 : m_blendingEnabled(false)
198 , m_alphaLayer(false)
199 , m_currentScale(1.0f)
204 void ShaderProgram::init()
206 m_program = createProgram(gVertexShader, gFragmentShader);
207 m_programInverted = createProgram(gVertexShader, gFragmentShaderInverted);
208 m_videoProgram = createProgram(gVideoVertexShader, gVideoFragmentShader);
209 m_surfTexOESProgram =
210 createProgram(gVertexShader, gSurfaceTextureOESFragmentShader);
211 m_surfTexOESProgramInverted =
212 createProgram(gVertexShader, gSurfaceTextureOESFragmentShaderInverted);
215 || m_programInverted == -1
216 || m_videoProgram == -1
217 || m_surfTexOESProgram == -1
218 || m_surfTexOESProgramInverted == -1)
221 m_hProjectionMatrix = glGetUniformLocation(m_program, "projectionMatrix");
222 m_hAlpha = glGetUniformLocation(m_program, "alpha");
223 m_hTexSampler = glGetUniformLocation(m_program, "s_texture");
224 m_hPosition = glGetAttribLocation(m_program, "vPosition");
226 m_hProjectionMatrixInverted = glGetUniformLocation(m_programInverted, "projectionMatrix");
227 m_hAlphaInverted = glGetUniformLocation(m_programInverted, "alpha");
228 m_hContrastInverted = glGetUniformLocation(m_surfTexOESProgramInverted, "contrast");
229 m_hTexSamplerInverted = glGetUniformLocation(m_programInverted, "s_texture");
230 m_hPositionInverted = glGetAttribLocation(m_programInverted, "vPosition");
232 m_hVideoProjectionMatrix =
233 glGetUniformLocation(m_videoProgram, "projectionMatrix");
234 m_hVideoTextureMatrix = glGetUniformLocation(m_videoProgram, "textureMatrix");
235 m_hVideoTexSampler = glGetUniformLocation(m_videoProgram, "s_yuvTexture");
236 m_hVideoPosition = glGetAttribLocation(m_program, "vPosition");
238 m_hSTOESProjectionMatrix =
239 glGetUniformLocation(m_surfTexOESProgram, "projectionMatrix");
240 m_hSTOESAlpha = glGetUniformLocation(m_surfTexOESProgram, "alpha");
241 m_hSTOESTexSampler = glGetUniformLocation(m_surfTexOESProgram, "s_texture");
242 m_hSTOESPosition = glGetAttribLocation(m_surfTexOESProgram, "vPosition");
244 m_hSTOESProjectionMatrixInverted =
245 glGetUniformLocation(m_surfTexOESProgramInverted, "projectionMatrix");
246 m_hSTOESAlphaInverted = glGetUniformLocation(m_surfTexOESProgramInverted, "alpha");
247 m_hSTOESContrastInverted = glGetUniformLocation(m_surfTexOESProgramInverted, "contrast");
248 m_hSTOESTexSamplerInverted = glGetUniformLocation(m_surfTexOESProgramInverted, "s_texture");
249 m_hSTOESPositionInverted = glGetAttribLocation(m_surfTexOESProgramInverted, "vPosition");
252 const GLfloat coord[] = {
259 glGenBuffers(1, m_textureBuffer);
260 glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
261 glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), coord, GL_STATIC_DRAW);
263 GLUtils::checkGlError("init");
266 void ShaderProgram::resetBlending()
269 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
270 glBlendEquation(GL_FUNC_ADD);
271 m_blendingEnabled = false;
274 void ShaderProgram::setBlendingState(bool enableBlending)
276 if (enableBlending == m_blendingEnabled)
284 m_blendingEnabled = enableBlending;
287 /////////////////////////////////////////////////////////////////////////////////////////
289 /////////////////////////////////////////////////////////////////////////////////////////
291 void ShaderProgram::setViewport(SkRect& viewport, float scale)
293 TransformationMatrix ortho;
294 GLUtils::setOrthographicMatrix(ortho, viewport.fLeft, viewport.fTop,
295 viewport.fRight, viewport.fBottom, -1000, 1000);
296 m_projectionMatrix = ortho;
297 m_viewport = viewport;
298 m_currentScale = scale;
301 void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrixHandle)
303 TransformationMatrix translate;
304 translate.translate3d(geometry.fLeft, geometry.fTop, 0.0);
305 TransformationMatrix scale;
306 scale.scale3d(geometry.width(), geometry.height(), 1.0);
308 TransformationMatrix total;
310 total = m_projectionMatrix * m_repositionMatrix * m_webViewMatrix
313 total = m_projectionMatrix * translate * scale;
315 GLfloat projectionMatrix[16];
316 GLUtils::toGLMatrix(projectionMatrix, total);
317 glUniformMatrix4fv(projectionMatrixHandle, 1, GL_FALSE, projectionMatrix);
320 void ShaderProgram::drawQuadInternal(SkRect& geometry,
324 GLint projectionMatrixHandle,
326 GLenum textureTarget,
332 glUseProgram(program);
334 if (!geometry.isEmpty())
335 setProjectionMatrix(geometry, projectionMatrixHandle);
337 TransformationMatrix matrix;
338 // Map x,y from (0,1) to (-1, 1)
339 matrix.scale3d(2, 2, 1);
340 matrix.translate3d(-0.5, -0.5, 0);
341 GLfloat projectionMatrix[16];
342 GLUtils::toGLMatrix(projectionMatrix, matrix);
343 glUniformMatrix4fv(projectionMatrixHandle, 1, GL_FALSE, projectionMatrix);
346 glActiveTexture(GL_TEXTURE0);
347 glUniform1i(texSampler, 0);
348 glBindTexture(textureTarget, textureId);
349 glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, texFilter);
350 glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, texFilter);
351 glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
352 glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
354 glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
355 glEnableVertexAttribArray(position);
356 glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0);
357 glUniform1f(alpha, opacity);
359 glUniform1f(contrast, m_contrast);
361 setBlendingState(opacity < 1.0);
362 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
365 void ShaderProgram::drawQuad(SkRect& geometry, int textureId, float opacity,
366 GLenum textureTarget, GLint texFilter)
368 if (textureTarget == GL_TEXTURE_2D) {
369 if (!TilesManager::instance()->invertedScreen()) {
370 drawQuadInternal(geometry, textureId, opacity, m_program,
372 m_hTexSampler, GL_TEXTURE_2D,
373 m_hPosition, m_hAlpha, texFilter);
375 // With the new GPU texture upload path, we do not use an FBO
376 // to blit the texture we receive from the TexturesGenerator thread.
377 // To implement inverted rendering, we thus have to do the rendering
378 // live, by using a different shader.
379 drawQuadInternal(geometry, textureId, opacity, m_programInverted,
380 m_hProjectionMatrixInverted,
381 m_hTexSamplerInverted, GL_TEXTURE_2D,
382 m_hPositionInverted, m_hAlphaInverted, texFilter,
383 m_hContrastInverted);
385 } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES
386 && !TilesManager::instance()->invertedScreen()) {
387 drawQuadInternal(geometry, textureId, opacity, m_surfTexOESProgram,
388 m_hSTOESProjectionMatrix,
389 m_hSTOESTexSampler, GL_TEXTURE_EXTERNAL_OES,
390 m_hSTOESPosition, m_hSTOESAlpha, texFilter);
391 } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES
392 && TilesManager::instance()->invertedScreen()) {
393 drawQuadInternal(geometry, textureId, opacity, m_surfTexOESProgramInverted,
394 m_hSTOESProjectionMatrixInverted,
395 m_hSTOESTexSamplerInverted, GL_TEXTURE_EXTERNAL_OES,
396 m_hSTOESPositionInverted, m_hSTOESAlphaInverted,
397 texFilter, m_hSTOESContrastInverted);
399 GLUtils::checkGlError("drawQuad");
402 void ShaderProgram::setViewRect(const IntRect& viewRect)
404 m_viewRect = viewRect;
406 // We do clipping using glScissor, which needs to take
407 // coordinates in screen space. The following matrix transform
408 // content coordinates in screen coordinates.
409 TransformationMatrix translate;
410 translate.translate(1.0, 1.0);
412 TransformationMatrix scale;
413 scale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1);
415 m_documentToScreenMatrix = scale * translate * m_projectionMatrix;
417 translate.scale3d(1, -1, 1);
418 m_documentToInvScreenMatrix = scale * translate * m_projectionMatrix;
420 IntRect rect(0, 0, m_webViewRect.width(), m_webViewRect.height());
421 m_documentViewport = m_documentToScreenMatrix.inverse().mapRect(rect);
424 // This function transform a clip rect extracted from the current layer
425 // into a clip rect in screen coordinates -- used by the clipping rects
426 FloatRect ShaderProgram::rectInScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
428 FloatRect srect(0, 0, size.width(), size.height());
429 TransformationMatrix renderMatrix = m_documentToScreenMatrix * drawMatrix;
430 return renderMatrix.mapRect(srect);
433 // used by the partial screen invals
434 FloatRect ShaderProgram::rectInInvScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
436 FloatRect srect(0, 0, size.width(), size.height());
437 TransformationMatrix renderMatrix = m_documentToInvScreenMatrix * drawMatrix;
438 return renderMatrix.mapRect(srect);
441 FloatRect ShaderProgram::rectInInvScreenCoord(const FloatRect& rect)
443 return m_documentToInvScreenMatrix.mapRect(rect);
446 FloatRect ShaderProgram::rectInScreenCoord(const FloatRect& rect)
448 return m_documentToScreenMatrix.mapRect(rect);
451 FloatRect ShaderProgram::convertScreenCoordToDocumentCoord(const FloatRect& rect)
453 return m_documentToScreenMatrix.inverse().mapRect(rect);
456 FloatRect ShaderProgram::convertInvScreenCoordToScreenCoord(const FloatRect& rect)
458 FloatRect documentRect = m_documentToInvScreenMatrix.inverse().mapRect(rect);
459 return rectInScreenCoord(documentRect);
462 FloatRect ShaderProgram::convertScreenCoordToInvScreenCoord(const FloatRect& rect)
464 FloatRect documentRect = m_documentToScreenMatrix.inverse().mapRect(rect);
465 return rectInInvScreenCoord(documentRect);
468 void ShaderProgram::setScreenClip(const IntRect& clip)
471 IntRect mclip = clip;
473 // the clip from frameworks is in full screen coordinates
474 mclip.setY(clip.y() - m_webViewRect.y() - m_titleBarHeight);
475 FloatRect tclip = convertInvScreenCoordToScreenCoord(mclip);
476 IntRect screenClip(tclip.x(), tclip.y(), tclip.width(), tclip.height());
477 m_screenClip = screenClip;
480 // clip is in screen coordinates
481 void ShaderProgram::clip(const FloatRect& clip)
483 if (clip == m_clipRect)
486 // we should only call glScissor in this function, so that we can easily
487 // track the current clipping rect.
489 IntRect screenClip(clip.x(),
491 clip.width(), clip.height());
493 if (!m_screenClip.isEmpty())
494 screenClip.intersect(m_screenClip);
496 screenClip.setY(screenClip.y() + m_viewRect.y());
497 if (screenClip.x() < 0) {
498 int w = screenClip.width();
501 screenClip.setWidth(w);
503 if (screenClip.y() < 0) {
504 int h = screenClip.height();
507 screenClip.setHeight(h);
510 glScissor(screenClip.x(), screenClip.y(), screenClip.width(), screenClip.height());
515 IntRect ShaderProgram::clippedRectWithViewport(const IntRect& rect, int margin)
517 IntRect viewport(m_viewport.fLeft - margin, m_viewport.fTop - margin,
518 m_viewport.width() + margin, m_viewport.height() + margin);
519 viewport.intersect(rect);
523 float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, float h)
525 TransformationMatrix modifiedDrawMatrix = drawMatrix;
526 modifiedDrawMatrix.scale3d(w, h, 1);
527 TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
528 FloatPoint3D point(0.5, 0.5, 0.0);
529 FloatPoint3D result = renderMatrix.mapPoint(point);
533 void ShaderProgram::drawLayerQuadInternal(const GLfloat* projectionMatrix,
534 int textureId, float opacity,
535 GLenum textureTarget, GLint program,
536 GLint matrix, GLint texSample,
537 GLint position, GLint alpha,
540 glUseProgram(program);
541 glUniformMatrix4fv(matrix, 1, GL_FALSE, projectionMatrix);
543 glActiveTexture(GL_TEXTURE0);
544 glUniform1i(texSample, 0);
545 glBindTexture(textureTarget, textureId);
546 glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
547 glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
548 glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
549 glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
552 glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
553 glEnableVertexAttribArray(position);
554 glVertexAttribPointer(position, 2, GL_FLOAT, GL_FALSE, 0, 0);
555 glUniform1f(alpha, opacity);
557 glUniform1f(contrast, m_contrast);
561 void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
562 const SkRect& geometry, int textureId,
563 float opacity, bool forceBlending,
564 GLenum textureTarget)
567 TransformationMatrix modifiedDrawMatrix = drawMatrix;
568 // move the drawing depending on where the texture is on the layer
569 modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
570 modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1);
572 TransformationMatrix renderMatrix;
574 renderMatrix = m_projectionMatrix * m_repositionMatrix
575 * m_webViewMatrix * modifiedDrawMatrix;
577 renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
579 GLfloat projectionMatrix[16];
580 GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
581 if (textureTarget == GL_TEXTURE_2D) {
582 if (!TilesManager::instance()->invertedScreen()) {
583 drawLayerQuadInternal(projectionMatrix, textureId, opacity,
584 GL_TEXTURE_2D, m_program,
585 m_hProjectionMatrix, m_hTexSampler,
586 m_hPosition, m_hAlpha);
588 drawLayerQuadInternal(projectionMatrix, textureId, opacity,
589 GL_TEXTURE_2D, m_programInverted,
590 m_hProjectionMatrixInverted, m_hTexSamplerInverted,
591 m_hPositionInverted, m_hAlphaInverted,
592 m_hContrastInverted);
594 } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES
595 && !TilesManager::instance()->invertedScreen()) {
596 drawLayerQuadInternal(projectionMatrix, textureId, opacity,
597 GL_TEXTURE_EXTERNAL_OES, m_surfTexOESProgram,
598 m_hSTOESProjectionMatrix, m_hSTOESTexSampler,
599 m_hSTOESPosition, m_hSTOESAlpha);
600 } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES
601 && TilesManager::instance()->invertedScreen()) {
602 drawLayerQuadInternal(projectionMatrix, textureId, opacity,
603 GL_TEXTURE_EXTERNAL_OES, m_surfTexOESProgramInverted,
604 m_hSTOESProjectionMatrixInverted, m_hSTOESTexSamplerInverted,
605 m_hSTOESPositionInverted, m_hSTOESAlphaInverted,
606 m_hSTOESContrastInverted);
609 setBlendingState(forceBlending || opacity < 1.0);
610 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
612 GLUtils::checkGlError("drawLayerQuad");
615 void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
616 float* textureMatrix, SkRect& geometry,
619 // switch to our custom yuv video rendering program
620 glUseProgram(m_videoProgram);
622 TransformationMatrix modifiedDrawMatrix = drawMatrix;
623 modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
624 modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1);
625 TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
627 GLfloat projectionMatrix[16];
628 GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
629 glUniformMatrix4fv(m_hVideoProjectionMatrix, 1, GL_FALSE, projectionMatrix);
630 glUniformMatrix4fv(m_hVideoTextureMatrix, 1, GL_FALSE, textureMatrix);
632 glActiveTexture(GL_TEXTURE0);
633 glUniform1i(m_hVideoTexSampler, 0);
634 glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
636 glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
637 glEnableVertexAttribArray(m_hVideoPosition);
638 glVertexAttribPointer(m_hVideoPosition, 2, GL_FLOAT, GL_FALSE, 0, 0);
640 setBlendingState(false);
641 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
644 void ShaderProgram::setWebViewMatrix(const float* matrix, bool alphaLayer)
646 GLUtils::convertToTransformationMatrix(matrix, m_webViewMatrix);
647 m_alphaLayer = alphaLayer;
650 void ShaderProgram::calculateAnimationDelta()
652 // The matrix contains the scrolling info, so this rect is starting from
654 // So we just need to map the webview's visible rect using the matrix,
655 // calculate the difference b/t transformed rect and the webViewRect,
656 // then we can get the delta x , y caused by the animation.
657 // Note that the Y is for reporting back to GL viewport, so it is inverted.
658 // When it is alpha animation, then we rely on the framework implementation
659 // such that there is no matrix applied in native webkit.
661 FloatRect rect(m_viewport.fLeft * m_currentScale,
662 m_viewport.fTop * m_currentScale,
663 m_webViewRect.width(),
664 m_webViewRect.height());
665 rect = m_webViewMatrix.mapRect(rect);
666 m_animationDelta.setX(rect.x() - m_webViewRect.x() );
667 m_animationDelta.setY(rect.y() + rect.height() - m_webViewRect.y()
668 - m_webViewRect.height() - m_titleBarHeight);
670 m_repositionMatrix.makeIdentity();
671 m_repositionMatrix.translate3d(-m_webViewRect.x(), -m_webViewRect.y() - m_titleBarHeight, 0);
672 m_repositionMatrix.translate3d(m_viewport.fLeft * m_currentScale, m_viewport.fTop * m_currentScale, 0);
673 m_repositionMatrix.translate3d(-m_animationDelta.x(), -m_animationDelta.y(), 0);
675 m_animationDelta.setX(0);
676 m_animationDelta.setY(0);
677 m_repositionMatrix.makeIdentity();
682 } // namespace WebCore
684 #endif // USE(ACCELERATED_COMPOSITING)