| Index: cc/CCRendererGL.cpp
|
| diff --git a/cc/CCRendererGL.cpp b/cc/CCRendererGL.cpp
|
| deleted file mode 100644
|
| index f28cc50c2f48b7f6c8025f45cc77f29c7df094d4..0000000000000000000000000000000000000000
|
| --- a/cc/CCRendererGL.cpp
|
| +++ /dev/null
|
| @@ -1,1530 +0,0 @@
|
| -// Copyright 2010 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -
|
| -#include "config.h"
|
| -
|
| -#if USE(ACCELERATED_COMPOSITING)
|
| -#include "CCRendererGL.h"
|
| -
|
| -#include "CCDamageTracker.h"
|
| -#include "CCLayerQuad.h"
|
| -#include "CCMathUtil.h"
|
| -#include "CCProxy.h"
|
| -#include "CCRenderPass.h"
|
| -#include "CCRenderSurfaceFilters.h"
|
| -#include "CCScopedTexture.h"
|
| -#include "CCSettings.h"
|
| -#include "CCSingleThreadProxy.h"
|
| -#include "CCVideoLayerImpl.h"
|
| -#include "Extensions3D.h"
|
| -#include "FloatQuad.h"
|
| -#include "GeometryBinding.h"
|
| -#include "GrTexture.h"
|
| -#include "NotImplemented.h"
|
| -#include "PlatformColor.h"
|
| -#include "SkBitmap.h"
|
| -#include "SkColor.h"
|
| -#include "TraceEvent.h"
|
| -#ifdef LOG
|
| -#undef LOG
|
| -#endif
|
| -#include "base/string_split.h"
|
| -#include "base/string_util.h"
|
| -#include <public/WebGraphicsContext3D.h>
|
| -#include <public/WebSharedGraphicsContext3D.h>
|
| -#include <public/WebVideoFrame.h>
|
| -#include <set>
|
| -#include <string>
|
| -#include <vector>
|
| -#include <wtf/CurrentTime.h>
|
| -#include <wtf/OwnArrayPtr.h>
|
| -
|
| -using namespace std;
|
| -using WebKit::WebGraphicsContext3D;
|
| -using WebKit::WebGraphicsMemoryAllocation;
|
| -using WebKit::WebSharedGraphicsContext3D;
|
| -using WebKit::WebTransformationMatrix;
|
| -
|
| -namespace cc {
|
| -
|
| -namespace {
|
| -
|
| -bool needsIOSurfaceReadbackWorkaround()
|
| -{
|
| -#if OS(DARWIN)
|
| - return true;
|
| -#else
|
| - return false;
|
| -#endif
|
| -}
|
| -
|
| -} // anonymous namespace
|
| -
|
| -PassOwnPtr<CCRendererGL> CCRendererGL::create(CCRendererClient* client, CCResourceProvider* resourceProvider)
|
| -{
|
| - OwnPtr<CCRendererGL> renderer(adoptPtr(new CCRendererGL(client, resourceProvider)));
|
| - if (!renderer->initialize())
|
| - return nullptr;
|
| -
|
| - return renderer.release();
|
| -}
|
| -
|
| -CCRendererGL::CCRendererGL(CCRendererClient* client,
|
| - CCResourceProvider* resourceProvider)
|
| - : CCDirectRenderer(client, resourceProvider)
|
| - , m_offscreenFramebufferId(0)
|
| - , m_sharedGeometryQuad(FloatRect(-0.5f, -0.5f, 1.0f, 1.0f))
|
| - , m_context(resourceProvider->graphicsContext3D())
|
| - , m_isViewportChanged(false)
|
| - , m_isFramebufferDiscarded(false)
|
| - , m_isUsingBindUniform(false)
|
| - , m_visible(true)
|
| -{
|
| - ASSERT(m_context);
|
| -}
|
| -
|
| -bool CCRendererGL::initialize()
|
| -{
|
| - if (!m_context->makeContextCurrent())
|
| - return false;
|
| -
|
| - m_context->setContextLostCallback(this);
|
| - m_context->pushGroupMarkerEXT("CompositorContext");
|
| -
|
| - std::string extensionsString = UTF16ToASCII(m_context->getString(GraphicsContext3D::EXTENSIONS));
|
| - std::vector<std::string> extensionsList;
|
| - base::SplitString(extensionsString, ' ', &extensionsList);
|
| - std::set<string> extensions(extensionsList.begin(), extensionsList.end());
|
| -
|
| - if (settings().acceleratePainting && extensions.count("GL_EXT_texture_format_BGRA8888")
|
| - && extensions.count("GL_EXT_read_format_bgra"))
|
| - m_capabilities.usingAcceleratedPainting = true;
|
| - else
|
| - m_capabilities.usingAcceleratedPainting = false;
|
| -
|
| -
|
| - m_capabilities.contextHasCachedFrontBuffer = extensions.count("GL_CHROMIUM_front_buffer_cached");
|
| -
|
| - m_capabilities.usingPartialSwap = CCSettings::partialSwapEnabled() && extensions.count("GL_CHROMIUM_post_sub_buffer");
|
| -
|
| - // Use the swapBuffers callback only with the threaded proxy.
|
| - if (CCProxy::hasImplThread())
|
| - m_capabilities.usingSwapCompleteCallback = extensions.count("GL_CHROMIUM_swapbuffers_complete_callback");
|
| - if (m_capabilities.usingSwapCompleteCallback)
|
| - m_context->setSwapBuffersCompleteCallbackCHROMIUM(this);
|
| -
|
| - m_capabilities.usingSetVisibility = extensions.count("GL_CHROMIUM_set_visibility");
|
| -
|
| - if (extensions.count("GL_CHROMIUM_iosurface"))
|
| - ASSERT(extensions.count("GL_ARB_texture_rectangle"));
|
| -
|
| - m_capabilities.usingGpuMemoryManager = extensions.count("GL_CHROMIUM_gpu_memory_manager");
|
| - if (m_capabilities.usingGpuMemoryManager)
|
| - m_context->setMemoryAllocationChangedCallbackCHROMIUM(this);
|
| -
|
| - m_capabilities.usingDiscardFramebuffer = extensions.count("GL_CHROMIUM_discard_framebuffer");
|
| -
|
| - m_capabilities.usingEglImage = extensions.count("GL_OES_EGL_image_external");
|
| -
|
| - GLC(m_context, m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_capabilities.maxTextureSize));
|
| - m_capabilities.bestTextureFormat = PlatformColor::bestTextureFormat(m_context, extensions.count("GL_EXT_texture_format_BGRA8888"));
|
| -
|
| - m_isUsingBindUniform = extensions.count("GL_CHROMIUM_bind_uniform_location");
|
| -
|
| - if (!initializeSharedObjects())
|
| - return false;
|
| -
|
| - // Make sure the viewport and context gets initialized, even if it is to zero.
|
| - viewportChanged();
|
| - return true;
|
| -}
|
| -
|
| -CCRendererGL::~CCRendererGL()
|
| -{
|
| - ASSERT(CCProxy::isImplThread());
|
| - m_context->setSwapBuffersCompleteCallbackCHROMIUM(0);
|
| - m_context->setMemoryAllocationChangedCallbackCHROMIUM(0);
|
| - m_context->setContextLostCallback(0);
|
| - cleanupSharedObjects();
|
| -}
|
| -
|
| -const RendererCapabilities& CCRendererGL::capabilities() const
|
| -{
|
| - return m_capabilities;
|
| -}
|
| -
|
| -WebGraphicsContext3D* CCRendererGL::context()
|
| -{
|
| - return m_context;
|
| -}
|
| -
|
| -void CCRendererGL::debugGLCall(WebGraphicsContext3D* context, const char* command, const char* file, int line)
|
| -{
|
| - unsigned long error = context->getError();
|
| - if (error != GraphicsContext3D::NO_ERROR)
|
| - LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));
|
| -}
|
| -
|
| -void CCRendererGL::setVisible(bool visible)
|
| -{
|
| - if (m_visible == visible)
|
| - return;
|
| - m_visible = visible;
|
| -
|
| - // TODO: Replace setVisibilityCHROMIUM with an extension to explicitly manage front/backbuffers
|
| - // crbug.com/116049
|
| - if (m_capabilities.usingSetVisibility)
|
| - m_context->setVisibilityCHROMIUM(visible);
|
| -}
|
| -
|
| -void CCRendererGL::releaseRenderPassTextures()
|
| -{
|
| - m_renderPassTextures.clear();
|
| -}
|
| -
|
| -void CCRendererGL::viewportChanged()
|
| -{
|
| - m_isViewportChanged = true;
|
| -}
|
| -
|
| -void CCRendererGL::clearFramebuffer(DrawingFrame& frame)
|
| -{
|
| - // On DEBUG builds, opaque render passes are cleared to blue to easily see regions that were not drawn on the screen.
|
| - if (frame.currentRenderPass->hasTransparentBackground())
|
| - GLC(m_context, m_context->clearColor(0, 0, 0, 0));
|
| - else
|
| - GLC(m_context, m_context->clearColor(0, 0, 1, 1));
|
| -
|
| -#if defined(NDEBUG)
|
| - if (frame.currentRenderPass->hasTransparentBackground())
|
| -#endif
|
| - m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
|
| -}
|
| -
|
| -void CCRendererGL::beginDrawingFrame(DrawingFrame& frame)
|
| -{
|
| - // FIXME: Remove this once framebuffer is automatically recreated on first use
|
| - ensureFramebuffer();
|
| -
|
| - if (viewportSize().isEmpty())
|
| - return;
|
| -
|
| - TRACE_EVENT0("cc", "CCRendererGL::drawLayers");
|
| - if (m_isViewportChanged) {
|
| - // Only reshape when we know we are going to draw. Otherwise, the reshape
|
| - // can leave the window at the wrong size if we never draw and the proper
|
| - // viewport size is never set.
|
| - m_isViewportChanged = false;
|
| - m_context->reshape(viewportWidth(), viewportHeight());
|
| - }
|
| -
|
| - makeContextCurrent();
|
| - // Bind the common vertex attributes used for drawing all the layers.
|
| - m_sharedGeometry->prepareForDraw();
|
| -
|
| - GLC(m_context, m_context->disable(GraphicsContext3D::DEPTH_TEST));
|
| - GLC(m_context, m_context->disable(GraphicsContext3D::CULL_FACE));
|
| - GLC(m_context, m_context->colorMask(true, true, true, true));
|
| - GLC(m_context, m_context->enable(GraphicsContext3D::BLEND));
|
| - GLC(m_context, m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
|
| -}
|
| -
|
| -void CCRendererGL::doNoOp()
|
| -{
|
| - GLC(m_context, m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
|
| - GLC(m_context, m_context->flush());
|
| -}
|
| -
|
| -void CCRendererGL::drawQuad(DrawingFrame& frame, const CCDrawQuad* quad)
|
| -{
|
| - if (quad->needsBlending())
|
| - GLC(m_context, m_context->enable(GraphicsContext3D::BLEND));
|
| - else
|
| - GLC(m_context, m_context->disable(GraphicsContext3D::BLEND));
|
| -
|
| - switch (quad->material()) {
|
| - case CCDrawQuad::Invalid:
|
| - ASSERT_NOT_REACHED();
|
| - break;
|
| - case CCDrawQuad::Checkerboard:
|
| - drawCheckerboardQuad(frame, CCCheckerboardDrawQuad::materialCast(quad));
|
| - break;
|
| - case CCDrawQuad::DebugBorder:
|
| - drawDebugBorderQuad(frame, CCDebugBorderDrawQuad::materialCast(quad));
|
| - break;
|
| - case CCDrawQuad::IOSurfaceContent:
|
| - drawIOSurfaceQuad(frame, CCIOSurfaceDrawQuad::materialCast(quad));
|
| - break;
|
| - case CCDrawQuad::RenderPass:
|
| - drawRenderPassQuad(frame, CCRenderPassDrawQuad::materialCast(quad));
|
| - break;
|
| - case CCDrawQuad::SolidColor:
|
| - drawSolidColorQuad(frame, CCSolidColorDrawQuad::materialCast(quad));
|
| - break;
|
| - case CCDrawQuad::StreamVideoContent:
|
| - drawStreamVideoQuad(frame, CCStreamVideoDrawQuad::materialCast(quad));
|
| - break;
|
| - case CCDrawQuad::TextureContent:
|
| - drawTextureQuad(frame, CCTextureDrawQuad::materialCast(quad));
|
| - break;
|
| - case CCDrawQuad::TiledContent:
|
| - drawTileQuad(frame, CCTileDrawQuad::materialCast(quad));
|
| - break;
|
| - case CCDrawQuad::YUVVideoContent:
|
| - drawYUVVideoQuad(frame, CCYUVVideoDrawQuad::materialCast(quad));
|
| - break;
|
| - }
|
| -}
|
| -
|
| -void CCRendererGL::drawCheckerboardQuad(const DrawingFrame& frame, const CCCheckerboardDrawQuad* quad)
|
| -{
|
| - const TileCheckerboardProgram* program = tileCheckerboardProgram();
|
| - ASSERT(program && program->initialized());
|
| - GLC(context(), context()->useProgram(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));
|
| -
|
| - const int checkerboardWidth = 16;
|
| - float frequency = 1.0 / checkerboardWidth;
|
| -
|
| - IntRect tileRect = quad->quadRect();
|
| - float texOffsetX = tileRect.x() % checkerboardWidth;
|
| - float texOffsetY = tileRect.y() % checkerboardWidth;
|
| - float texScaleX = tileRect.width();
|
| - float texScaleY = tileRect.height();
|
| - GLC(context(), context()->uniform4f(program->fragmentShader().texTransformLocation(), texOffsetX, texOffsetY, texScaleX, texScaleY));
|
| -
|
| - GLC(context(), context()->uniform1f(program->fragmentShader().frequencyLocation(), frequency));
|
| -
|
| - setShaderOpacity(quad->opacity(), program->fragmentShader().alphaLocation());
|
| - drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), program->vertexShader().matrixLocation());
|
| -}
|
| -
|
| -void CCRendererGL::drawDebugBorderQuad(const DrawingFrame& frame, const CCDebugBorderDrawQuad* quad)
|
| -{
|
| - static float glMatrix[16];
|
| - const SolidColorProgram* program = solidColorProgram();
|
| - ASSERT(program && program->initialized());
|
| - GLC(context(), context()->useProgram(program->program()));
|
| -
|
| - // Use the full quadRect for debug quads to not move the edges based on partial swaps.
|
| - const IntRect& layerRect = quad->quadRect();
|
| - WebTransformationMatrix renderMatrix = quad->quadTransform();
|
| - renderMatrix.translate(0.5 * layerRect.width() + layerRect.x(), 0.5 * layerRect.height() + layerRect.y());
|
| - renderMatrix.scaleNonUniform(layerRect.width(), layerRect.height());
|
| - CCRendererGL::toGLMatrix(&glMatrix[0], frame.projectionMatrix * renderMatrix);
|
| - GLC(context(), context()->uniformMatrix4fv(program->vertexShader().matrixLocation(), 1, false, &glMatrix[0]));
|
| -
|
| - SkColor color = quad->color();
|
| - float alpha = SkColorGetA(color) / 255.0;
|
| -
|
| - GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation(), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, (SkColorGetB(color) / 255.0) * alpha, alpha));
|
| -
|
| - 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(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short)));
|
| -}
|
| -
|
| -static inline SkBitmap applyFilters(CCRendererGL* renderer, const WebKit::WebFilterOperations& filters, CCScopedTexture* sourceTexture)
|
| -{
|
| - if (filters.isEmpty())
|
| - return SkBitmap();
|
| -
|
| - WebGraphicsContext3D* filterContext = CCProxy::hasImplThread() ? WebSharedGraphicsContext3D::compositorThreadContext() : WebSharedGraphicsContext3D::mainThreadContext();
|
| - GrContext* filterGrContext = CCProxy::hasImplThread() ? WebSharedGraphicsContext3D::compositorThreadGrContext() : WebSharedGraphicsContext3D::mainThreadGrContext();
|
| -
|
| - if (!filterContext || !filterGrContext)
|
| - return SkBitmap();
|
| -
|
| - renderer->context()->flush();
|
| -
|
| - CCResourceProvider::ScopedWriteLockGL lock(renderer->resourceProvider(), sourceTexture->id());
|
| - SkBitmap source = CCRenderSurfaceFilters::apply(filters, lock.textureId(), sourceTexture->size(), filterContext, filterGrContext);
|
| - return source;
|
| -}
|
| -
|
| -PassOwnPtr<CCScopedTexture> CCRendererGL::drawBackgroundFilters(DrawingFrame& frame, const CCRenderPassDrawQuad* quad, const WebKit::WebFilterOperations& filters, const WebTransformationMatrix& contentsDeviceTransform)
|
| -{
|
| - // This method draws a background filter, which applies a filter to any pixels behind the quad and seen through its background.
|
| - // The algorithm works as follows:
|
| - // 1. Compute a bounding box around the pixels that will be visible through the quad.
|
| - // 2. Read the pixels in the bounding box into a buffer R.
|
| - // 3. Apply the background filter to R, so that it is applied in the pixels' coordinate space.
|
| - // 4. Apply the quad's inverse transform to map the pixels in R into the quad's content space. This implicitly
|
| - // clips R by the content bounds of the quad since the destination texture has bounds matching the quad's content.
|
| - // 5. Draw the background texture for the contents using the same transform as used to draw the contents itself. This is done
|
| - // without blending to replace the current background pixels with the new filtered background.
|
| - // 6. Draw the contents of the quad over drop of the new background with blending, as per usual. The filtered background
|
| - // pixels will show through any non-opaque pixels in this draws.
|
| - //
|
| - // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5.
|
| -
|
| - // FIXME: When this algorithm changes, update CCLayerTreeHost::prioritizeTextures() accordingly.
|
| -
|
| - if (filters.isEmpty())
|
| - return nullptr;
|
| -
|
| - // FIXME: We only allow background filters on an opaque render surface because other surfaces may contain
|
| - // translucent pixels, and the contents behind those translucent pixels wouldn't have the filter applied.
|
| - if (frame.currentRenderPass->hasTransparentBackground())
|
| - return nullptr;
|
| - ASSERT(!frame.currentTexture);
|
| -
|
| - // FIXME: Do a single readback for both the surface and replica and cache the filtered results (once filter textures are not reused).
|
| - IntRect deviceRect = enclosingIntRect(CCMathUtil::mapClippedRect(contentsDeviceTransform, sharedGeometryQuad().boundingBox()));
|
| -
|
| - int top, right, bottom, left;
|
| - filters.getOutsets(top, right, bottom, left);
|
| - deviceRect.move(-left, -top);
|
| - deviceRect.expand(left + right, top + bottom);
|
| -
|
| - deviceRect.intersect(frame.currentRenderPass->outputRect());
|
| -
|
| - OwnPtr<CCScopedTexture> deviceBackgroundTexture = CCScopedTexture::create(m_resourceProvider);
|
| - if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect))
|
| - return nullptr;
|
| -
|
| - SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgroundTexture.get());
|
| - if (!filteredDeviceBackground.getTexture())
|
| - return nullptr;
|
| -
|
| - GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.getTexture());
|
| - int filteredDeviceBackgroundTextureId = texture->getTextureHandle();
|
| -
|
| - OwnPtr<CCScopedTexture> backgroundTexture = CCScopedTexture::create(m_resourceProvider);
|
| - if (!backgroundTexture->allocate(CCRenderer::ImplPool, quad->quadRect().size(), GraphicsContext3D::RGBA, CCResourceProvider::TextureUsageFramebuffer))
|
| - return nullptr;
|
| -
|
| - const CCRenderPass* targetRenderPass = frame.currentRenderPass;
|
| - bool usingBackgroundTexture = useScopedTexture(frame, backgroundTexture.get(), quad->quadRect());
|
| -
|
| - if (usingBackgroundTexture) {
|
| - // Copy the readback pixels from device to the background texture for the surface.
|
| - WebTransformationMatrix deviceToFramebufferTransform;
|
| - deviceToFramebufferTransform.translate(quad->quadRect().width() / 2.0, quad->quadRect().height() / 2.0);
|
| - deviceToFramebufferTransform.scale3d(quad->quadRect().width(), quad->quadRect().height(), 1);
|
| - deviceToFramebufferTransform.multiply(contentsDeviceTransform.inverse());
|
| - copyTextureToFramebuffer(frame, filteredDeviceBackgroundTextureId, deviceRect, deviceToFramebufferTransform);
|
| - }
|
| -
|
| - useRenderPass(frame, targetRenderPass);
|
| -
|
| - if (!usingBackgroundTexture)
|
| - return nullptr;
|
| - return backgroundTexture.release();
|
| -}
|
| -
|
| -void CCRendererGL::drawRenderPassQuad(DrawingFrame& frame, const CCRenderPassDrawQuad* quad)
|
| -{
|
| - CachedTexture* contentsTexture = m_renderPassTextures.get(quad->renderPassId());
|
| - if (!contentsTexture || !contentsTexture->id())
|
| - return;
|
| -
|
| - const CCRenderPass* renderPass = frame.renderPassesById->get(quad->renderPassId());
|
| - ASSERT(renderPass);
|
| - if (!renderPass)
|
| - return;
|
| -
|
| - WebTransformationMatrix renderMatrix = quad->quadTransform();
|
| - renderMatrix.translate(0.5 * quad->quadRect().width() + quad->quadRect().x(), 0.5 * quad->quadRect().height() + quad->quadRect().y());
|
| - WebTransformationMatrix deviceMatrix = renderMatrix;
|
| - deviceMatrix.scaleNonUniform(quad->quadRect().width(), quad->quadRect().height());
|
| - WebTransformationMatrix contentsDeviceTransform = WebTransformationMatrix(frame.windowMatrix * frame.projectionMatrix * deviceMatrix).to2dTransform();
|
| -
|
| - // Can only draw surface if device matrix is invertible.
|
| - if (!contentsDeviceTransform.isInvertible())
|
| - return;
|
| -
|
| - OwnPtr<CCScopedTexture> backgroundTexture = drawBackgroundFilters(frame, quad, renderPass->backgroundFilters(), contentsDeviceTransform);
|
| -
|
| - // FIXME: Cache this value so that we don't have to do it for both the surface and its replica.
|
| - // Apply filters to the contents texture.
|
| - SkBitmap filterBitmap = applyFilters(this, renderPass->filters(), contentsTexture);
|
| - OwnPtr<CCResourceProvider::ScopedReadLockGL> contentsResourceLock;
|
| - unsigned contentsTextureId = 0;
|
| - if (filterBitmap.getTexture()) {
|
| - GrTexture* texture = reinterpret_cast<GrTexture*>(filterBitmap.getTexture());
|
| - contentsTextureId = texture->getTextureHandle();
|
| - } else {
|
| - contentsResourceLock = adoptPtr(new CCResourceProvider::ScopedReadLockGL(m_resourceProvider, contentsTexture->id()));
|
| - contentsTextureId = contentsResourceLock->textureId();
|
| - }
|
| -
|
| - // Draw the background texture if there is one.
|
| - if (backgroundTexture) {
|
| - ASSERT(backgroundTexture->size() == quad->quadRect().size());
|
| - CCResourceProvider::ScopedReadLockGL lock(m_resourceProvider, backgroundTexture->id());
|
| - copyTextureToFramebuffer(frame, lock.textureId(), quad->quadRect(), quad->quadTransform());
|
| - }
|
| -
|
| - bool clipped = false;
|
| - FloatQuad deviceQuad = CCMathUtil::mapQuad(contentsDeviceTransform, sharedGeometryQuad(), clipped);
|
| - ASSERT(!clipped);
|
| - CCLayerQuad deviceLayerBounds = CCLayerQuad(FloatQuad(deviceQuad.boundingBox()));
|
| - CCLayerQuad deviceLayerEdges = CCLayerQuad(deviceQuad);
|
| -
|
| - // Use anti-aliasing programs only when necessary.
|
| - bool useAA = (!deviceQuad.isRectilinear() || !deviceQuad.boundingBox().isExpressibleAsIntRect());
|
| - if (useAA) {
|
| - deviceLayerBounds.inflateAntiAliasingDistance();
|
| - deviceLayerEdges.inflateAntiAliasingDistance();
|
| - }
|
| -
|
| - OwnPtr<CCResourceProvider::ScopedReadLockGL> maskResourceLock;
|
| - unsigned maskTextureId = 0;
|
| - if (quad->maskResourceId()) {
|
| - maskResourceLock = adoptPtr(new CCResourceProvider::ScopedReadLockGL(m_resourceProvider, quad->maskResourceId()));
|
| - maskTextureId = maskResourceLock->textureId();
|
| - }
|
| -
|
| - // FIXME: use the backgroundTexture and blend the background in with this draw instead of having a separate copy of the background texture.
|
| -
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
|
| - context()->bindTexture(GraphicsContext3D::TEXTURE_2D, contentsTextureId);
|
| -
|
| - int shaderQuadLocation = -1;
|
| - int shaderEdgeLocation = -1;
|
| - int shaderMaskSamplerLocation = -1;
|
| - int shaderMaskTexCoordScaleLocation = -1;
|
| - int shaderMaskTexCoordOffsetLocation = -1;
|
| - int shaderMatrixLocation = -1;
|
| - int shaderAlphaLocation = -1;
|
| - if (useAA && maskTextureId) {
|
| - const RenderPassMaskProgramAA* program = renderPassMaskProgramAA();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
| -
|
| - shaderQuadLocation = program->vertexShader().pointLocation();
|
| - shaderEdgeLocation = program->fragmentShader().edgeLocation();
|
| - shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocation();
|
| - shaderMaskTexCoordScaleLocation = program->fragmentShader().maskTexCoordScaleLocation();
|
| - shaderMaskTexCoordOffsetLocation = program->fragmentShader().maskTexCoordOffsetLocation();
|
| - shaderMatrixLocation = program->vertexShader().matrixLocation();
|
| - shaderAlphaLocation = program->fragmentShader().alphaLocation();
|
| - } else if (!useAA && maskTextureId) {
|
| - const RenderPassMaskProgram* program = renderPassMaskProgram();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
| -
|
| - shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocation();
|
| - shaderMaskTexCoordScaleLocation = program->fragmentShader().maskTexCoordScaleLocation();
|
| - shaderMaskTexCoordOffsetLocation = program->fragmentShader().maskTexCoordOffsetLocation();
|
| - shaderMatrixLocation = program->vertexShader().matrixLocation();
|
| - shaderAlphaLocation = program->fragmentShader().alphaLocation();
|
| - } else if (useAA && !maskTextureId) {
|
| - const RenderPassProgramAA* program = renderPassProgramAA();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
| -
|
| - shaderQuadLocation = program->vertexShader().pointLocation();
|
| - shaderEdgeLocation = program->fragmentShader().edgeLocation();
|
| - shaderMatrixLocation = program->vertexShader().matrixLocation();
|
| - shaderAlphaLocation = program->fragmentShader().alphaLocation();
|
| - } else {
|
| - const RenderPassProgram* program = renderPassProgram();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
| -
|
| - shaderMatrixLocation = program->vertexShader().matrixLocation();
|
| - shaderAlphaLocation = program->fragmentShader().alphaLocation();
|
| - }
|
| -
|
| - if (shaderMaskSamplerLocation != -1) {
|
| - ASSERT(shaderMaskTexCoordScaleLocation != 1);
|
| - ASSERT(shaderMaskTexCoordOffsetLocation != 1);
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE1));
|
| - GLC(context(), context()->uniform1i(shaderMaskSamplerLocation, 1));
|
| - GLC(context(), context()->uniform2f(shaderMaskTexCoordScaleLocation, quad->maskTexCoordScaleX(), quad->maskTexCoordScaleY()));
|
| - GLC(context(), context()->uniform2f(shaderMaskTexCoordOffsetLocation, quad->maskTexCoordOffsetX(), quad->maskTexCoordOffsetY()));
|
| - context()->bindTexture(GraphicsContext3D::TEXTURE_2D, maskTextureId);
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
|
| - }
|
| -
|
| - if (shaderEdgeLocation != -1) {
|
| - float edge[24];
|
| - deviceLayerEdges.toFloatArray(edge);
|
| - deviceLayerBounds.toFloatArray(&edge[12]);
|
| - GLC(context(), context()->uniform3fv(shaderEdgeLocation, 8, edge));
|
| - }
|
| -
|
| - // Map device space quad to surface space. contentsDeviceTransform has no 3d component since it was generated with to2dTransform() so we don't need to project.
|
| - FloatQuad surfaceQuad = CCMathUtil::mapQuad(contentsDeviceTransform.inverse(), deviceLayerEdges.floatQuad(), clipped);
|
| - ASSERT(!clipped);
|
| -
|
| - setShaderOpacity(quad->opacity(), shaderAlphaLocation);
|
| - setShaderFloatQuad(surfaceQuad, shaderQuadLocation);
|
| - drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), shaderMatrixLocation);
|
| -}
|
| -
|
| -void CCRendererGL::drawSolidColorQuad(const DrawingFrame& frame, const CCSolidColorDrawQuad* quad)
|
| -{
|
| - const SolidColorProgram* program = solidColorProgram();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| -
|
| - SkColor color = quad->color();
|
| - float opacity = quad->opacity();
|
| - float alpha = (SkColorGetA(color) / 255.0) * opacity;
|
| -
|
| - GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation(), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, (SkColorGetB(color) / 255.0) * alpha, alpha));
|
| -
|
| - drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), program->vertexShader().matrixLocation());
|
| -}
|
| -
|
| -struct TileProgramUniforms {
|
| - unsigned program;
|
| - unsigned samplerLocation;
|
| - unsigned vertexTexTransformLocation;
|
| - unsigned fragmentTexTransformLocation;
|
| - unsigned edgeLocation;
|
| - unsigned matrixLocation;
|
| - unsigned alphaLocation;
|
| - unsigned pointLocation;
|
| -};
|
| -
|
| -template<class T>
|
| -static void tileUniformLocation(T program, TileProgramUniforms& uniforms)
|
| -{
|
| - uniforms.program = program->program();
|
| - uniforms.vertexTexTransformLocation = program->vertexShader().vertexTexTransformLocation();
|
| - uniforms.matrixLocation = program->vertexShader().matrixLocation();
|
| - uniforms.pointLocation = program->vertexShader().pointLocation();
|
| -
|
| - uniforms.samplerLocation = program->fragmentShader().samplerLocation();
|
| - uniforms.alphaLocation = program->fragmentShader().alphaLocation();
|
| - uniforms.fragmentTexTransformLocation = program->fragmentShader().fragmentTexTransformLocation();
|
| - uniforms.edgeLocation = program->fragmentShader().edgeLocation();
|
| -}
|
| -
|
| -void CCRendererGL::drawTileQuad(const DrawingFrame& frame, const CCTileDrawQuad* quad)
|
| -{
|
| - IntRect tileRect = quad->quadVisibleRect();
|
| -
|
| - FloatRect clampRect(tileRect);
|
| - // Clamp texture coordinates to avoid sampling outside the layer
|
| - // by deflating the tile region half a texel or half a texel
|
| - // minus epsilon for one pixel layers. The resulting clamp region
|
| - // is mapped to the unit square by the vertex shader and mapped
|
| - // back to normalized texture coordinates by the fragment shader
|
| - // after being clamped to 0-1 range.
|
| - const float epsilon = 1 / 1024.0f;
|
| - float clampX = min(0.5, clampRect.width() / 2.0 - epsilon);
|
| - float clampY = min(0.5, clampRect.height() / 2.0 - epsilon);
|
| - clampRect.inflateX(-clampX);
|
| - clampRect.inflateY(-clampY);
|
| - FloatSize clampOffset = clampRect.minXMinYCorner() - FloatRect(tileRect).minXMinYCorner();
|
| -
|
| - FloatPoint textureOffset = quad->textureOffset() + clampOffset +
|
| - IntPoint(tileRect.location() - quad->quadRect().location());
|
| -
|
| - // Map clamping rectangle to unit square.
|
| - float vertexTexTranslateX = -clampRect.x() / clampRect.width();
|
| - float vertexTexTranslateY = -clampRect.y() / clampRect.height();
|
| - float vertexTexScaleX = tileRect.width() / clampRect.width();
|
| - float vertexTexScaleY = tileRect.height() / clampRect.height();
|
| -
|
| - // Map to normalized texture coordinates.
|
| - const IntSize& textureSize = quad->textureSize();
|
| - float fragmentTexTranslateX = textureOffset.x() / textureSize.width();
|
| - float fragmentTexTranslateY = textureOffset.y() / textureSize.height();
|
| - float fragmentTexScaleX = clampRect.width() / textureSize.width();
|
| - float fragmentTexScaleY = clampRect.height() / textureSize.height();
|
| -
|
| -
|
| - FloatQuad localQuad;
|
| - WebTransformationMatrix deviceTransform = WebTransformationMatrix(frame.windowMatrix * frame.projectionMatrix * quad->quadTransform()).to2dTransform();
|
| - if (!deviceTransform.isInvertible())
|
| - return;
|
| -
|
| - bool clipped = false;
|
| - FloatQuad deviceLayerQuad = CCMathUtil::mapQuad(deviceTransform, FloatQuad(quad->visibleContentRect()), clipped);
|
| - ASSERT(!clipped);
|
| -
|
| - TileProgramUniforms uniforms;
|
| - // For now, we simply skip anti-aliasing with the quad is clipped. This only happens
|
| - // on perspective transformed layers that go partially behind the camera.
|
| - if (quad->isAntialiased() && !clipped) {
|
| - if (quad->swizzleContents())
|
| - tileUniformLocation(tileProgramSwizzleAA(), uniforms);
|
| - else
|
| - tileUniformLocation(tileProgramAA(), uniforms);
|
| - } else {
|
| - if (quad->needsBlending()) {
|
| - if (quad->swizzleContents())
|
| - tileUniformLocation(tileProgramSwizzle(), uniforms);
|
| - else
|
| - tileUniformLocation(tileProgram(), uniforms);
|
| - } else {
|
| - if (quad->swizzleContents())
|
| - tileUniformLocation(tileProgramSwizzleOpaque(), uniforms);
|
| - else
|
| - tileUniformLocation(tileProgramOpaque(), uniforms);
|
| - }
|
| - }
|
| -
|
| - GLC(context(), context()->useProgram(uniforms.program));
|
| - GLC(context(), context()->uniform1i(uniforms.samplerLocation, 0));
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
|
| - CCResourceProvider::ScopedReadLockGL quadResourceLock(m_resourceProvider, quad->resourceId());
|
| - GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, quadResourceLock.textureId()));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, quad->textureFilter()));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, quad->textureFilter()));
|
| -
|
| - bool useAA = !clipped && quad->isAntialiased();
|
| - if (useAA) {
|
| - CCLayerQuad deviceLayerBounds = CCLayerQuad(FloatQuad(deviceLayerQuad.boundingBox()));
|
| - deviceLayerBounds.inflateAntiAliasingDistance();
|
| -
|
| - CCLayerQuad deviceLayerEdges = CCLayerQuad(deviceLayerQuad);
|
| - deviceLayerEdges.inflateAntiAliasingDistance();
|
| -
|
| - float edge[24];
|
| - deviceLayerEdges.toFloatArray(edge);
|
| - deviceLayerBounds.toFloatArray(&edge[12]);
|
| - GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge));
|
| -
|
| - GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation, vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY));
|
| - GLC(context(), context()->uniform4f(uniforms.fragmentTexTransformLocation, fragmentTexTranslateX, fragmentTexTranslateY, fragmentTexScaleX, fragmentTexScaleY));
|
| -
|
| - FloatPoint bottomRight(tileRect.maxX(), tileRect.maxY());
|
| - FloatPoint bottomLeft(tileRect.x(), tileRect.maxY());
|
| - FloatPoint topLeft(tileRect.x(), tileRect.y());
|
| - FloatPoint topRight(tileRect.maxX(), tileRect.y());
|
| -
|
| - // Map points to device space.
|
| - bottomRight = CCMathUtil::mapPoint(deviceTransform, bottomRight, clipped);
|
| - ASSERT(!clipped);
|
| - bottomLeft = CCMathUtil::mapPoint(deviceTransform, bottomLeft, clipped);
|
| - ASSERT(!clipped);
|
| - topLeft = CCMathUtil::mapPoint(deviceTransform, topLeft, clipped);
|
| - ASSERT(!clipped);
|
| - topRight = CCMathUtil::mapPoint(deviceTransform, topRight, clipped);
|
| - ASSERT(!clipped);
|
| -
|
| - CCLayerQuad::Edge bottomEdge(bottomRight, bottomLeft);
|
| - CCLayerQuad::Edge leftEdge(bottomLeft, topLeft);
|
| - CCLayerQuad::Edge topEdge(topLeft, topRight);
|
| - CCLayerQuad::Edge rightEdge(topRight, bottomRight);
|
| -
|
| - // Only apply anti-aliasing to edges not clipped by culling or scissoring.
|
| - if (quad->topEdgeAA() && tileRect.y() == quad->quadRect().y())
|
| - topEdge = deviceLayerEdges.top();
|
| - if (quad->leftEdgeAA() && tileRect.x() == quad->quadRect().x())
|
| - leftEdge = deviceLayerEdges.left();
|
| - if (quad->rightEdgeAA() && tileRect.maxX() == quad->quadRect().maxX())
|
| - rightEdge = deviceLayerEdges.right();
|
| - if (quad->bottomEdgeAA() && tileRect.maxY() == quad->quadRect().maxY())
|
| - bottomEdge = deviceLayerEdges.bottom();
|
| -
|
| - float sign = FloatQuad(tileRect).isCounterclockwise() ? -1 : 1;
|
| - bottomEdge.scale(sign);
|
| - leftEdge.scale(sign);
|
| - topEdge.scale(sign);
|
| - rightEdge.scale(sign);
|
| -
|
| - // Create device space quad.
|
| - CCLayerQuad deviceQuad(leftEdge, topEdge, rightEdge, bottomEdge);
|
| -
|
| - // Map device space quad to local space. contentsDeviceTransform has no 3d component since it was generated with to2dTransform() so we don't need to project.
|
| - WebTransformationMatrix inverseDeviceTransform = deviceTransform.inverse();
|
| - localQuad = CCMathUtil::mapQuad(inverseDeviceTransform, deviceQuad.floatQuad(), clipped);
|
| -
|
| - // We should not ASSERT(!clipped) here, because anti-aliasing inflation may cause deviceQuad to become
|
| - // clipped. To our knowledge this scenario does not need to be handled differently than the unclipped case.
|
| - } else {
|
| - // Move fragment shader transform to vertex shader. We can do this while
|
| - // still producing correct results as fragmentTexTransformLocation
|
| - // should always be non-negative when tiles are transformed in a way
|
| - // that could result in sampling outside the layer.
|
| - vertexTexScaleX *= fragmentTexScaleX;
|
| - vertexTexScaleY *= fragmentTexScaleY;
|
| - vertexTexTranslateX *= fragmentTexScaleX;
|
| - vertexTexTranslateY *= fragmentTexScaleY;
|
| - vertexTexTranslateX += fragmentTexTranslateX;
|
| - vertexTexTranslateY += fragmentTexTranslateY;
|
| -
|
| - GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation, vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY));
|
| -
|
| - localQuad = FloatRect(tileRect);
|
| - }
|
| -
|
| - // Normalize to tileRect.
|
| - localQuad.scale(1.0f / tileRect.width(), 1.0f / tileRect.height());
|
| -
|
| - setShaderOpacity(quad->opacity(), uniforms.alphaLocation);
|
| - setShaderFloatQuad(localQuad, uniforms.pointLocation);
|
| -
|
| - // The tile quad shader behaves differently compared to all other shaders.
|
| - // The transform and vertex data are used to figure out the extents that the
|
| - // un-antialiased quad should have and which vertex this is and the float
|
| - // quad passed in via uniform is the actual geometry that gets used to draw
|
| - // it. This is why this centered rect is used and not the original quadRect.
|
| - FloatRect centeredRect(FloatPoint(-0.5 * tileRect.width(), -0.5 * tileRect.height()), tileRect.size());
|
| - drawQuadGeometry(frame, quad->quadTransform(), centeredRect, uniforms.matrixLocation);
|
| -}
|
| -
|
| -void CCRendererGL::drawYUVVideoQuad(const DrawingFrame& frame, const CCYUVVideoDrawQuad* quad)
|
| -{
|
| - const VideoYUVProgram* program = videoYUVProgram();
|
| - ASSERT(program && program->initialized());
|
| -
|
| - const CCVideoLayerImpl::FramePlane& yPlane = quad->yPlane();
|
| - const CCVideoLayerImpl::FramePlane& uPlane = quad->uPlane();
|
| - const CCVideoLayerImpl::FramePlane& vPlane = quad->vPlane();
|
| -
|
| - CCResourceProvider::ScopedReadLockGL yPlaneLock(m_resourceProvider, yPlane.resourceId);
|
| - CCResourceProvider::ScopedReadLockGL uPlaneLock(m_resourceProvider, uPlane.resourceId);
|
| - CCResourceProvider::ScopedReadLockGL vPlaneLock(m_resourceProvider, vPlane.resourceId);
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE1));
|
| - GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, yPlaneLock.textureId()));
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE2));
|
| - GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, uPlaneLock.textureId()));
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE3));
|
| - GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, vPlaneLock.textureId()));
|
| -
|
| - GLC(context(), context()->useProgram(program->program()));
|
| -
|
| - float yWidthScaleFactor = static_cast<float>(yPlane.visibleSize.width()) / yPlane.size.width();
|
| - // Arbitrarily take the u sizes because u and v dimensions are identical.
|
| - float uvWidthScaleFactor = static_cast<float>(uPlane.visibleSize.width()) / uPlane.size.width();
|
| - GLC(context(), context()->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
|
| - GLC(context(), context()->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
|
| -
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().yTextureLocation(), 1));
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().uTextureLocation(), 2));
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().vTextureLocation(), 3));
|
| -
|
| - // These values are magic numbers that are used in the transformation from YUV to RGB color values.
|
| - // They are taken from the following webpage: http://www.fourcc.org/fccyvrgb.php
|
| - float yuv2RGB[9] = {
|
| - 1.164f, 1.164f, 1.164f,
|
| - 0.f, -.391f, 2.018f,
|
| - 1.596f, -.813f, 0.f,
|
| - };
|
| - GLC(context(), context()->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 1, 0, yuv2RGB));
|
| -
|
| - // These values map to 16, 128, and 128 respectively, and are computed
|
| - // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
|
| - // They are used in the YUV to RGBA conversion formula:
|
| - // Y - 16 : Gives 16 values of head and footroom for overshooting
|
| - // U - 128 : Turns unsigned U into signed U [-128,127]
|
| - // V - 128 : Turns unsigned V into signed V [-128,127]
|
| - float yuvAdjust[3] = {
|
| - -0.0625f,
|
| - -0.5f,
|
| - -0.5f,
|
| - };
|
| - GLC(context(), context()->uniform3fv(program->fragmentShader().yuvAdjLocation(), 1, yuvAdjust));
|
| -
|
| - setShaderOpacity(quad->opacity(), program->fragmentShader().alphaLocation());
|
| - drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), program->vertexShader().matrixLocation());
|
| -
|
| - // Reset active texture back to texture 0.
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
|
| -}
|
| -
|
| -void CCRendererGL::drawStreamVideoQuad(const DrawingFrame& frame, const CCStreamVideoDrawQuad* quad)
|
| -{
|
| - static float glMatrix[16];
|
| -
|
| - ASSERT(m_capabilities.usingEglImage);
|
| -
|
| - const VideoStreamTextureProgram* program = videoStreamTextureProgram();
|
| - GLC(context(), context()->useProgram(program->program()));
|
| -
|
| - toGLMatrix(&glMatrix[0], quad->matrix());
|
| - GLC(context(), context()->uniformMatrix4fv(program->vertexShader().texMatrixLocation(), 1, false, glMatrix));
|
| -
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
|
| - GLC(context(), context()->bindTexture(Extensions3DChromium::GL_TEXTURE_EXTERNAL_OES, quad->textureId()));
|
| -
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
| -
|
| - setShaderOpacity(quad->opacity(), program->fragmentShader().alphaLocation());
|
| - drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), program->vertexShader().matrixLocation());
|
| -}
|
| -
|
| -struct TextureProgramBinding {
|
| - template<class Program> void set(Program* program)
|
| - {
|
| - ASSERT(program && program->initialized());
|
| - programId = program->program();
|
| - samplerLocation = program->fragmentShader().samplerLocation();
|
| - matrixLocation = program->vertexShader().matrixLocation();
|
| - alphaLocation = program->fragmentShader().alphaLocation();
|
| - }
|
| - int programId;
|
| - int samplerLocation;
|
| - int matrixLocation;
|
| - int alphaLocation;
|
| -};
|
| -
|
| -struct TexTransformTextureProgramBinding : TextureProgramBinding {
|
| - template<class Program> void set(Program* program)
|
| - {
|
| - TextureProgramBinding::set(program);
|
| - texTransformLocation = program->vertexShader().texTransformLocation();
|
| - }
|
| - int texTransformLocation;
|
| -};
|
| -
|
| -void CCRendererGL::drawTextureQuad(const DrawingFrame& frame, const CCTextureDrawQuad* quad)
|
| -{
|
| - ASSERT(CCProxy::isImplThread());
|
| -
|
| - TexTransformTextureProgramBinding binding;
|
| - if (quad->flipped())
|
| - binding.set(textureProgramFlip());
|
| - else
|
| - binding.set(textureProgram());
|
| - GLC(context(), context()->useProgram(binding.programId));
|
| - GLC(context(), context()->uniform1i(binding.samplerLocation, 0));
|
| - const FloatRect& uvRect = quad->uvRect();
|
| - GLC(context(), context()->uniform4f(binding.texTransformLocation, uvRect.x(), uvRect.y(), uvRect.width(), uvRect.height()));
|
| -
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
|
| - CCResourceProvider::ScopedReadLockGL quadResourceLock(m_resourceProvider, quad->resourceId());
|
| - GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, quadResourceLock.textureId()));
|
| -
|
| - // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
|
| - // where it will only happen once per texture.
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
|
| -
|
| - if (!quad->premultipliedAlpha()) {
|
| - // 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(GraphicsContext3D::SRC_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA, GraphicsContext3D::ZERO, GraphicsContext3D::ONE));
|
| - }
|
| -
|
| - setShaderOpacity(quad->opacity(), binding.alphaLocation);
|
| - drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), binding.matrixLocation);
|
| -
|
| - if (!quad->premultipliedAlpha())
|
| - GLC(m_context, m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
|
| -}
|
| -
|
| -void CCRendererGL::drawIOSurfaceQuad(const DrawingFrame& frame, const CCIOSurfaceDrawQuad* quad)
|
| -{
|
| - ASSERT(CCProxy::isImplThread());
|
| - TexTransformTextureProgramBinding binding;
|
| - binding.set(textureIOSurfaceProgram());
|
| -
|
| - GLC(context(), context()->useProgram(binding.programId));
|
| - GLC(context(), context()->uniform1i(binding.samplerLocation, 0));
|
| - if (quad->orientation() == CCIOSurfaceDrawQuad::Flipped)
|
| - GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, quad->ioSurfaceSize().height(), quad->ioSurfaceSize().width(), quad->ioSurfaceSize().height() * -1.0));
|
| - else
|
| - GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, 0, quad->ioSurfaceSize().width(), quad->ioSurfaceSize().height()));
|
| -
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
|
| - GLC(context(), context()->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, quad->ioSurfaceTextureId()));
|
| -
|
| - setShaderOpacity(quad->opacity(), binding.alphaLocation);
|
| - drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), binding.matrixLocation);
|
| -
|
| - GLC(context(), context()->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, 0));
|
| -}
|
| -
|
| -void CCRendererGL::finishDrawingFrame(DrawingFrame& frame)
|
| -{
|
| - m_currentFramebufferLock.clear();
|
| - m_swapBufferRect.unite(enclosingIntRect(frame.rootDamageRect));
|
| -
|
| - GLC(m_context, m_context->disable(GraphicsContext3D::SCISSOR_TEST));
|
| - GLC(m_context, m_context->disable(GraphicsContext3D::BLEND));
|
| -}
|
| -
|
| -bool CCRendererGL::flippedFramebuffer() const
|
| -{
|
| - return true;
|
| -}
|
| -
|
| -void CCRendererGL::toGLMatrix(float* flattened, const WebTransformationMatrix& m)
|
| -{
|
| - flattened[0] = m.m11();
|
| - flattened[1] = m.m12();
|
| - flattened[2] = m.m13();
|
| - flattened[3] = m.m14();
|
| - flattened[4] = m.m21();
|
| - flattened[5] = m.m22();
|
| - flattened[6] = m.m23();
|
| - flattened[7] = m.m24();
|
| - flattened[8] = m.m31();
|
| - flattened[9] = m.m32();
|
| - flattened[10] = m.m33();
|
| - flattened[11] = m.m34();
|
| - flattened[12] = m.m41();
|
| - flattened[13] = m.m42();
|
| - flattened[14] = m.m43();
|
| - flattened[15] = m.m44();
|
| -}
|
| -
|
| -void CCRendererGL::setShaderFloatQuad(const FloatQuad& quad, int quadLocation)
|
| -{
|
| - if (quadLocation == -1)
|
| - return;
|
| -
|
| - float point[8];
|
| - point[0] = quad.p1().x();
|
| - point[1] = quad.p1().y();
|
| - point[2] = quad.p2().x();
|
| - point[3] = quad.p2().y();
|
| - point[4] = quad.p3().x();
|
| - point[5] = quad.p3().y();
|
| - point[6] = quad.p4().x();
|
| - point[7] = quad.p4().y();
|
| - GLC(m_context, m_context->uniform2fv(quadLocation, 4, point));
|
| -}
|
| -
|
| -void CCRendererGL::setShaderOpacity(float opacity, int alphaLocation)
|
| -{
|
| - if (alphaLocation != -1)
|
| - GLC(m_context, m_context->uniform1f(alphaLocation, opacity));
|
| -}
|
| -
|
| -void CCRendererGL::drawQuadGeometry(const DrawingFrame& frame, const WebKit::WebTransformationMatrix& drawTransform, const FloatRect& quadRect, int matrixLocation)
|
| -{
|
| - WebTransformationMatrix quadRectMatrix;
|
| - quadRectTransform(&quadRectMatrix, drawTransform, quadRect);
|
| - static float glMatrix[16];
|
| - toGLMatrix(&glMatrix[0], frame.projectionMatrix * quadRectMatrix);
|
| - GLC(m_context, m_context->uniformMatrix4fv(matrixLocation, 1, false, &glMatrix[0]));
|
| -
|
| - GLC(m_context, m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0));
|
| -}
|
| -
|
| -void CCRendererGL::copyTextureToFramebuffer(const DrawingFrame& frame, int textureId, const IntRect& rect, const WebTransformationMatrix& drawMatrix)
|
| -{
|
| - const RenderPassProgram* program = renderPassProgram();
|
| -
|
| - GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
|
| - GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
|
| - GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
|
| -
|
| - GLC(context(), context()->useProgram(program->program()));
|
| - GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
|
| - setShaderOpacity(1, program->fragmentShader().alphaLocation());
|
| - drawQuadGeometry(frame, drawMatrix, rect, program->vertexShader().matrixLocation());
|
| -}
|
| -
|
| -void CCRendererGL::finish()
|
| -{
|
| - TRACE_EVENT0("cc", "CCRendererGL::finish");
|
| - m_context->finish();
|
| -}
|
| -
|
| -bool CCRendererGL::swapBuffers()
|
| -{
|
| - ASSERT(m_visible);
|
| - ASSERT(!m_isFramebufferDiscarded);
|
| -
|
| - TRACE_EVENT0("cc", "CCRendererGL::swapBuffers");
|
| - // We're done! Time to swapbuffers!
|
| -
|
| - if (m_capabilities.usingPartialSwap) {
|
| - // If supported, we can save significant bandwidth by only swapping the damaged/scissored region (clamped to the viewport)
|
| - m_swapBufferRect.intersect(IntRect(IntPoint(), viewportSize()));
|
| - int flippedYPosOfRectBottom = viewportHeight() - m_swapBufferRect.y() - m_swapBufferRect.height();
|
| - m_context->postSubBufferCHROMIUM(m_swapBufferRect.x(), flippedYPosOfRectBottom, m_swapBufferRect.width(), m_swapBufferRect.height());
|
| - } else {
|
| - // Note that currently this has the same effect as swapBuffers; we should
|
| - // consider exposing a different entry point on WebGraphicsContext3D.
|
| - m_context->prepareTexture();
|
| - }
|
| -
|
| - m_swapBufferRect = IntRect();
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void CCRendererGL::onSwapBuffersComplete()
|
| -{
|
| - m_client->onSwapBuffersComplete();
|
| -}
|
| -
|
| -void CCRendererGL::onMemoryAllocationChanged(WebGraphicsMemoryAllocation allocation)
|
| -{
|
| - // FIXME: This is called on the main thread in single threaded mode, but we expect it on the impl thread.
|
| - if (!CCProxy::hasImplThread()) {
|
| - ASSERT(CCProxy::isMainThread());
|
| - DebugScopedSetImplThread impl;
|
| - onMemoryAllocationChangedOnImplThread(allocation);
|
| - } else {
|
| - ASSERT(CCProxy::isImplThread());
|
| - onMemoryAllocationChangedOnImplThread(allocation);
|
| - }
|
| -}
|
| -
|
| -void CCRendererGL::onMemoryAllocationChangedOnImplThread(WebKit::WebGraphicsMemoryAllocation allocation)
|
| -{
|
| - if (m_visible && !allocation.gpuResourceSizeInBytes)
|
| - return;
|
| -
|
| - if (!allocation.suggestHaveBackbuffer && !m_visible)
|
| - discardFramebuffer();
|
| -
|
| - if (!allocation.gpuResourceSizeInBytes) {
|
| - releaseRenderPassTextures();
|
| - m_client->releaseContentsTextures();
|
| - GLC(m_context, m_context->flush());
|
| - } else
|
| - m_client->setMemoryAllocationLimitBytes(allocation.gpuResourceSizeInBytes);
|
| -}
|
| -
|
| -void CCRendererGL::discardFramebuffer()
|
| -{
|
| - if (m_isFramebufferDiscarded)
|
| - return;
|
| -
|
| - if (!m_capabilities.usingDiscardFramebuffer)
|
| - return;
|
| -
|
| - // FIXME: Update attachments argument to appropriate values once they are no longer ignored.
|
| - m_context->discardFramebufferEXT(GraphicsContext3D::TEXTURE_2D, 0, 0);
|
| - m_isFramebufferDiscarded = true;
|
| -
|
| - // Damage tracker needs a full reset every time framebuffer is discarded.
|
| - m_client->setFullRootLayerDamage();
|
| -}
|
| -
|
| -void CCRendererGL::ensureFramebuffer()
|
| -{
|
| - if (!m_isFramebufferDiscarded)
|
| - return;
|
| -
|
| - if (!m_capabilities.usingDiscardFramebuffer)
|
| - return;
|
| -
|
| - m_context->ensureFramebufferCHROMIUM();
|
| - m_isFramebufferDiscarded = false;
|
| -}
|
| -
|
| -void CCRendererGL::onContextLost()
|
| -{
|
| - m_client->didLoseContext();
|
| -}
|
| -
|
| -
|
| -void CCRendererGL::getFramebufferPixels(void *pixels, const IntRect& rect)
|
| -{
|
| - ASSERT(rect.maxX() <= viewportWidth() && rect.maxY() <= viewportHeight());
|
| -
|
| - if (!pixels)
|
| - return;
|
| -
|
| - makeContextCurrent();
|
| -
|
| - bool doWorkaround = needsIOSurfaceReadbackWorkaround();
|
| -
|
| - Platform3DObject temporaryTexture = 0;
|
| - Platform3DObject temporaryFBO = 0;
|
| -
|
| - if (doWorkaround) {
|
| - // On Mac OS X, calling glReadPixels against an FBO whose color attachment is an
|
| - // IOSurface-backed texture causes corruption of future glReadPixels calls, even those on
|
| - // different OpenGL contexts. It is believed that this is the root cause of top crasher
|
| - // http://crbug.com/99393. <rdar://problem/10949687>
|
| -
|
| - temporaryTexture = m_context->createTexture();
|
| - GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, temporaryTexture));
|
| - GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
|
| - GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
|
| - GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
|
| - GLC(m_context, m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
|
| - // Copy the contents of the current (IOSurface-backed) framebuffer into a temporary texture.
|
| - GLC(m_context, m_context->copyTexImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 0, 0, viewportSize().width(), viewportSize().height(), 0));
|
| - temporaryFBO = m_context->createFramebuffer();
|
| - // Attach this texture to an FBO, and perform the readback from that FBO.
|
| - GLC(m_context, m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, temporaryFBO));
|
| - GLC(m_context, m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, temporaryTexture, 0));
|
| -
|
| - ASSERT(m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) == GraphicsContext3D::FRAMEBUFFER_COMPLETE);
|
| - }
|
| -
|
| - OwnArrayPtr<uint8_t> srcPixels = adoptArrayPtr(new uint8_t[rect.width() * rect.height() * 4]);
|
| - GLC(m_context, m_context->readPixels(rect.x(), viewportSize().height() - rect.maxY(), rect.width(), rect.height(),
|
| - GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, srcPixels.get()));
|
| -
|
| - uint8_t* destPixels = static_cast<uint8_t*>(pixels);
|
| - size_t rowBytes = rect.width() * 4;
|
| - int numRows = rect.height();
|
| - size_t totalBytes = numRows * rowBytes;
|
| - for (size_t destY = 0; destY < totalBytes; destY += rowBytes) {
|
| - // Flip Y axis.
|
| - size_t srcY = totalBytes - destY - rowBytes;
|
| - // Swizzle BGRA -> RGBA.
|
| - for (size_t x = 0; x < rowBytes; x += 4) {
|
| - destPixels[destY + (x+0)] = srcPixels.get()[srcY + (x+2)];
|
| - destPixels[destY + (x+1)] = srcPixels.get()[srcY + (x+1)];
|
| - destPixels[destY + (x+2)] = srcPixels.get()[srcY + (x+0)];
|
| - destPixels[destY + (x+3)] = srcPixels.get()[srcY + (x+3)];
|
| - }
|
| - }
|
| -
|
| - if (doWorkaround) {
|
| - // Clean up.
|
| - GLC(m_context, m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
|
| - GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0));
|
| - GLC(m_context, m_context->deleteFramebuffer(temporaryFBO));
|
| - GLC(m_context, m_context->deleteTexture(temporaryTexture));
|
| - }
|
| -
|
| - if (!m_visible) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::getFramebufferPixels dropping resources after readback");
|
| - discardFramebuffer();
|
| - releaseRenderPassTextures();
|
| - m_client->releaseContentsTextures();
|
| - GLC(m_context, m_context->flush());
|
| - }
|
| -}
|
| -
|
| -bool CCRendererGL::getFramebufferTexture(CCScopedTexture* texture, const IntRect& deviceRect)
|
| -{
|
| - ASSERT(!texture->id() || (texture->size() == deviceRect.size() && texture->format() == GraphicsContext3D::RGB));
|
| -
|
| - if (!texture->id() && !texture->allocate(CCRenderer::ImplPool, deviceRect.size(), GraphicsContext3D::RGB, CCResourceProvider::TextureUsageAny))
|
| - return false;
|
| -
|
| - CCResourceProvider::ScopedWriteLockGL lock(m_resourceProvider, texture->id());
|
| - GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, lock.textureId()));
|
| - GLC(m_context, m_context->copyTexImage2D(GraphicsContext3D::TEXTURE_2D, 0, texture->format(),
|
| - deviceRect.x(), deviceRect.y(), deviceRect.width(), deviceRect.height(), 0));
|
| - return true;
|
| -}
|
| -
|
| -bool CCRendererGL::useScopedTexture(DrawingFrame& frame, const CCScopedTexture* texture, const IntRect& viewportRect)
|
| -{
|
| - ASSERT(texture->id());
|
| - frame.currentRenderPass = 0;
|
| - frame.currentTexture = texture;
|
| -
|
| - return bindFramebufferToTexture(frame, texture, viewportRect);
|
| -}
|
| -
|
| -void CCRendererGL::bindFramebufferToOutputSurface(DrawingFrame& frame)
|
| -{
|
| - m_currentFramebufferLock.clear();
|
| - GLC(m_context, m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
|
| -}
|
| -
|
| -bool CCRendererGL::bindFramebufferToTexture(DrawingFrame& frame, const CCScopedTexture* texture, const IntRect& framebufferRect)
|
| -{
|
| - ASSERT(texture->id());
|
| -
|
| - GLC(m_context, m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_offscreenFramebufferId));
|
| - m_currentFramebufferLock = adoptPtr(new CCResourceProvider::ScopedWriteLockGL(m_resourceProvider, texture->id()));
|
| - unsigned textureId = m_currentFramebufferLock->textureId();
|
| - GLC(m_context, m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, textureId, 0));
|
| -
|
| -#if !defined ( NDEBUG )
|
| - if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
|
| - ASSERT_NOT_REACHED();
|
| - return false;
|
| - }
|
| -#endif
|
| -
|
| - initializeMatrices(frame, framebufferRect, false);
|
| - setDrawViewportSize(framebufferRect.size());
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void CCRendererGL::enableScissorTestRect(const IntRect& scissorRect)
|
| -{
|
| - GLC(m_context, m_context->enable(GraphicsContext3D::SCISSOR_TEST));
|
| - GLC(m_context, m_context->scissor(scissorRect.x(), scissorRect.y(), scissorRect.width(), scissorRect.height()));
|
| -}
|
| -
|
| -void CCRendererGL::disableScissorTest()
|
| -{
|
| - GLC(m_context, m_context->disable(GraphicsContext3D::SCISSOR_TEST));
|
| -}
|
| -
|
| -void CCRendererGL::setDrawViewportSize(const IntSize& viewportSize)
|
| -{
|
| - GLC(m_context, m_context->viewport(0, 0, viewportSize.width(), viewportSize.height()));
|
| -}
|
| -
|
| -bool CCRendererGL::makeContextCurrent()
|
| -{
|
| - return m_context->makeContextCurrent();
|
| -}
|
| -
|
| -bool CCRendererGL::initializeSharedObjects()
|
| -{
|
| - TRACE_EVENT0("cc", "CCRendererGL::initializeSharedObjects");
|
| - makeContextCurrent();
|
| -
|
| - // Create an FBO for doing offscreen rendering.
|
| - GLC(m_context, m_offscreenFramebufferId = m_context->createFramebuffer());
|
| -
|
| - // We will always need these programs to render, so create the programs eagerly so that the shader compilation can
|
| - // start while we do other work. Other programs are created lazily on first access.
|
| - m_sharedGeometry = adoptPtr(new GeometryBinding(m_context, quadVertexRect()));
|
| - m_renderPassProgram = adoptPtr(new RenderPassProgram(m_context));
|
| - m_tileProgram = adoptPtr(new TileProgram(m_context));
|
| - m_tileProgramOpaque = adoptPtr(new TileProgramOpaque(m_context));
|
| -
|
| - GLC(m_context, m_context->flush());
|
| -
|
| - return true;
|
| -}
|
| -
|
| -const CCRendererGL::TileCheckerboardProgram* CCRendererGL::tileCheckerboardProgram()
|
| -{
|
| - if (!m_tileCheckerboardProgram)
|
| - m_tileCheckerboardProgram = adoptPtr(new TileCheckerboardProgram(m_context));
|
| - if (!m_tileCheckerboardProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::checkerboardProgram::initalize");
|
| - m_tileCheckerboardProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_tileCheckerboardProgram.get();
|
| -}
|
| -
|
| -const CCRendererGL::SolidColorProgram* CCRendererGL::solidColorProgram()
|
| -{
|
| - if (!m_solidColorProgram)
|
| - m_solidColorProgram = adoptPtr(new SolidColorProgram(m_context));
|
| - if (!m_solidColorProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::solidColorProgram::initialize");
|
| - m_solidColorProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_solidColorProgram.get();
|
| -}
|
| -
|
| -const CCRendererGL::RenderPassProgram* CCRendererGL::renderPassProgram()
|
| -{
|
| - ASSERT(m_renderPassProgram);
|
| - if (!m_renderPassProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::renderPassProgram::initialize");
|
| - m_renderPassProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_renderPassProgram.get();
|
| -}
|
| -
|
| -const CCRendererGL::RenderPassProgramAA* CCRendererGL::renderPassProgramAA()
|
| -{
|
| - if (!m_renderPassProgramAA)
|
| - m_renderPassProgramAA = adoptPtr(new RenderPassProgramAA(m_context));
|
| - if (!m_renderPassProgramAA->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::renderPassProgramAA::initialize");
|
| - m_renderPassProgramAA->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_renderPassProgramAA.get();
|
| -}
|
| -
|
| -const CCRendererGL::RenderPassMaskProgram* CCRendererGL::renderPassMaskProgram()
|
| -{
|
| - if (!m_renderPassMaskProgram)
|
| - m_renderPassMaskProgram = adoptPtr(new RenderPassMaskProgram(m_context));
|
| - if (!m_renderPassMaskProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::renderPassMaskProgram::initialize");
|
| - m_renderPassMaskProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_renderPassMaskProgram.get();
|
| -}
|
| -
|
| -const CCRendererGL::RenderPassMaskProgramAA* CCRendererGL::renderPassMaskProgramAA()
|
| -{
|
| - if (!m_renderPassMaskProgramAA)
|
| - m_renderPassMaskProgramAA = adoptPtr(new RenderPassMaskProgramAA(m_context));
|
| - if (!m_renderPassMaskProgramAA->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::renderPassMaskProgramAA::initialize");
|
| - m_renderPassMaskProgramAA->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_renderPassMaskProgramAA.get();
|
| -}
|
| -
|
| -const CCRendererGL::TileProgram* CCRendererGL::tileProgram()
|
| -{
|
| - ASSERT(m_tileProgram);
|
| - if (!m_tileProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::tileProgram::initialize");
|
| - m_tileProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_tileProgram.get();
|
| -}
|
| -
|
| -const CCRendererGL::TileProgramOpaque* CCRendererGL::tileProgramOpaque()
|
| -{
|
| - ASSERT(m_tileProgramOpaque);
|
| - if (!m_tileProgramOpaque->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::tileProgramOpaque::initialize");
|
| - m_tileProgramOpaque->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_tileProgramOpaque.get();
|
| -}
|
| -
|
| -const CCRendererGL::TileProgramAA* CCRendererGL::tileProgramAA()
|
| -{
|
| - if (!m_tileProgramAA)
|
| - m_tileProgramAA = adoptPtr(new TileProgramAA(m_context));
|
| - if (!m_tileProgramAA->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::tileProgramAA::initialize");
|
| - m_tileProgramAA->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_tileProgramAA.get();
|
| -}
|
| -
|
| -const CCRendererGL::TileProgramSwizzle* CCRendererGL::tileProgramSwizzle()
|
| -{
|
| - if (!m_tileProgramSwizzle)
|
| - m_tileProgramSwizzle = adoptPtr(new TileProgramSwizzle(m_context));
|
| - if (!m_tileProgramSwizzle->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::tileProgramSwizzle::initialize");
|
| - m_tileProgramSwizzle->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_tileProgramSwizzle.get();
|
| -}
|
| -
|
| -const CCRendererGL::TileProgramSwizzleOpaque* CCRendererGL::tileProgramSwizzleOpaque()
|
| -{
|
| - if (!m_tileProgramSwizzleOpaque)
|
| - m_tileProgramSwizzleOpaque = adoptPtr(new TileProgramSwizzleOpaque(m_context));
|
| - if (!m_tileProgramSwizzleOpaque->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::tileProgramSwizzleOpaque::initialize");
|
| - m_tileProgramSwizzleOpaque->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_tileProgramSwizzleOpaque.get();
|
| -}
|
| -
|
| -const CCRendererGL::TileProgramSwizzleAA* CCRendererGL::tileProgramSwizzleAA()
|
| -{
|
| - if (!m_tileProgramSwizzleAA)
|
| - m_tileProgramSwizzleAA = adoptPtr(new TileProgramSwizzleAA(m_context));
|
| - if (!m_tileProgramSwizzleAA->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::tileProgramSwizzleAA::initialize");
|
| - m_tileProgramSwizzleAA->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_tileProgramSwizzleAA.get();
|
| -}
|
| -
|
| -const CCRendererGL::TextureProgram* CCRendererGL::textureProgram()
|
| -{
|
| - if (!m_textureProgram)
|
| - m_textureProgram = adoptPtr(new TextureProgram(m_context));
|
| - if (!m_textureProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::textureProgram::initialize");
|
| - m_textureProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_textureProgram.get();
|
| -}
|
| -
|
| -const CCRendererGL::TextureProgramFlip* CCRendererGL::textureProgramFlip()
|
| -{
|
| - if (!m_textureProgramFlip)
|
| - m_textureProgramFlip = adoptPtr(new TextureProgramFlip(m_context));
|
| - if (!m_textureProgramFlip->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::textureProgramFlip::initialize");
|
| - m_textureProgramFlip->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_textureProgramFlip.get();
|
| -}
|
| -
|
| -const CCRendererGL::TextureIOSurfaceProgram* CCRendererGL::textureIOSurfaceProgram()
|
| -{
|
| - if (!m_textureIOSurfaceProgram)
|
| - m_textureIOSurfaceProgram = adoptPtr(new TextureIOSurfaceProgram(m_context));
|
| - if (!m_textureIOSurfaceProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::textureIOSurfaceProgram::initialize");
|
| - m_textureIOSurfaceProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_textureIOSurfaceProgram.get();
|
| -}
|
| -
|
| -const CCRendererGL::VideoYUVProgram* CCRendererGL::videoYUVProgram()
|
| -{
|
| - if (!m_videoYUVProgram)
|
| - m_videoYUVProgram = adoptPtr(new VideoYUVProgram(m_context));
|
| - if (!m_videoYUVProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::videoYUVProgram::initialize");
|
| - m_videoYUVProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_videoYUVProgram.get();
|
| -}
|
| -
|
| -const CCRendererGL::VideoStreamTextureProgram* CCRendererGL::videoStreamTextureProgram()
|
| -{
|
| - if (!m_videoStreamTextureProgram)
|
| - m_videoStreamTextureProgram = adoptPtr(new VideoStreamTextureProgram(m_context));
|
| - if (!m_videoStreamTextureProgram->initialized()) {
|
| - TRACE_EVENT0("cc", "CCRendererGL::streamTextureProgram::initialize");
|
| - m_videoStreamTextureProgram->initialize(m_context, m_isUsingBindUniform);
|
| - }
|
| - return m_videoStreamTextureProgram.get();
|
| -}
|
| -
|
| -void CCRendererGL::cleanupSharedObjects()
|
| -{
|
| - makeContextCurrent();
|
| -
|
| - m_sharedGeometry.clear();
|
| -
|
| - if (m_tileProgram)
|
| - m_tileProgram->cleanup(m_context);
|
| - if (m_tileProgramOpaque)
|
| - m_tileProgramOpaque->cleanup(m_context);
|
| - if (m_tileProgramSwizzle)
|
| - m_tileProgramSwizzle->cleanup(m_context);
|
| - if (m_tileProgramSwizzleOpaque)
|
| - m_tileProgramSwizzleOpaque->cleanup(m_context);
|
| - if (m_tileProgramAA)
|
| - m_tileProgramAA->cleanup(m_context);
|
| - if (m_tileProgramSwizzleAA)
|
| - m_tileProgramSwizzleAA->cleanup(m_context);
|
| - if (m_tileCheckerboardProgram)
|
| - m_tileCheckerboardProgram->cleanup(m_context);
|
| -
|
| - if (m_renderPassMaskProgram)
|
| - m_renderPassMaskProgram->cleanup(m_context);
|
| - if (m_renderPassProgram)
|
| - m_renderPassProgram->cleanup(m_context);
|
| - if (m_renderPassMaskProgramAA)
|
| - m_renderPassMaskProgramAA->cleanup(m_context);
|
| - if (m_renderPassProgramAA)
|
| - m_renderPassProgramAA->cleanup(m_context);
|
| -
|
| - if (m_textureProgram)
|
| - m_textureProgram->cleanup(m_context);
|
| - if (m_textureProgramFlip)
|
| - m_textureProgramFlip->cleanup(m_context);
|
| - if (m_textureIOSurfaceProgram)
|
| - m_textureIOSurfaceProgram->cleanup(m_context);
|
| -
|
| - if (m_videoYUVProgram)
|
| - m_videoYUVProgram->cleanup(m_context);
|
| - if (m_videoStreamTextureProgram)
|
| - m_videoStreamTextureProgram->cleanup(m_context);
|
| -
|
| - if (m_solidColorProgram)
|
| - m_solidColorProgram->cleanup(m_context);
|
| -
|
| - if (m_offscreenFramebufferId)
|
| - GLC(m_context, m_context->deleteFramebuffer(m_offscreenFramebufferId));
|
| -
|
| - releaseRenderPassTextures();
|
| -}
|
| -
|
| -bool CCRendererGL::isContextLost()
|
| -{
|
| - return (m_context->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR);
|
| -}
|
| -
|
| -} // namespace cc
|
| -
|
| -#endif // USE(ACCELERATED_COMPOSITING)
|
|
|