| Index: cc/throttled_texture_uploader.cc
|
| diff --git a/cc/throttled_texture_uploader.cc b/cc/throttled_texture_uploader.cc
|
| index 179f2b61d1922974b29b2da08bfe3c10360eb5ec..0e3f8291784516c50ead3a4f2f59fd8e653fc144 100644
|
| --- a/cc/throttled_texture_uploader.cc
|
| +++ b/cc/throttled_texture_uploader.cc
|
| @@ -5,13 +5,20 @@
|
| #include "config.h"
|
| #include "ThrottledTextureUploader.h"
|
|
|
| +#include "CCPrioritizedTexture.h"
|
| +#include "CCProxy.h"
|
| #include "Extensions3DChromium.h"
|
| +#include "SkGpuDevice.h"
|
| #include "TraceEvent.h"
|
| #include <algorithm>
|
| #include <public/Platform.h>
|
| #include <public/WebGraphicsContext3D.h>
|
| +#include <public/WebSharedGraphicsContext3D.h>
|
| #include <vector>
|
|
|
| +using WebKit::WebGraphicsContext3D;
|
| +using WebKit::WebSharedGraphicsContext3D;
|
| +
|
| namespace {
|
|
|
| // How many previous uploads to use when predicting future throughput.
|
| @@ -22,6 +29,22 @@ static const size_t uploadHistorySize = 100;
|
| // More than one thread will not access this variable, so we do not need to synchronize access.
|
| static double estimatedTexturesPerSecondGlobal = 48.0 * 60.0;
|
|
|
| +PassOwnPtr<SkCanvas> createAcceleratedCanvas(GrContext* grContext,
|
| + cc::IntSize canvasSize,
|
| + unsigned textureId)
|
| +{
|
| + GrPlatformTextureDesc textureDesc;
|
| + textureDesc.fFlags = kRenderTarget_GrPlatformTextureFlag;
|
| + textureDesc.fWidth = canvasSize.width();
|
| + textureDesc.fHeight = canvasSize.height();
|
| + textureDesc.fConfig = kSkia8888_GrPixelConfig;
|
| + textureDesc.fTextureHandle = textureId;
|
| + SkAutoTUnref<GrTexture> target(
|
| + grContext->createPlatformTexture(textureDesc));
|
| + SkAutoTUnref<SkDevice> device(new SkGpuDevice(grContext, target.get()));
|
| + return adoptPtr(new SkCanvas(device.get()));
|
| +}
|
| +
|
| } // anonymous namespace
|
|
|
| namespace cc {
|
| @@ -150,13 +173,84 @@ void ThrottledTextureUploader::endQuery()
|
|
|
| void ThrottledTextureUploader::uploadTexture(CCResourceProvider* resourceProvider, Parameters upload)
|
| {
|
| - bool isFullUpload = upload.destOffset.isZero() &&
|
| - upload.sourceRect.size() == upload.texture->texture()->size();
|
| + bool isFullUpload = upload.geometry.destOffset.isZero() &&
|
| + upload.geometry.sourceRect.size() == upload.texture->size();
|
|
|
| if (isFullUpload)
|
| beginQuery();
|
|
|
| - upload.texture->updateRect(resourceProvider, upload.sourceRect, upload.destOffset);
|
| + if (upload.bitmap) {
|
| + upload.bitmap->lockPixels();
|
| + upload.texture->upload(
|
| + resourceProvider,
|
| + static_cast<const uint8_t*>(upload.bitmap->getPixels()),
|
| + upload.geometry.contentRect,
|
| + upload.geometry.sourceRect,
|
| + upload.geometry.destOffset);
|
| + upload.bitmap->unlockPixels();
|
| + }
|
| +
|
| + // TODO(reveman): Move this logic to CCTextureUpdateController after
|
| + // removing Parameters struct.
|
| + if (upload.picture) {
|
| + CCPrioritizedTexture* texture = upload.texture;
|
| + IntRect pictureRect = upload.geometry.contentRect;
|
| + IntRect sourceRect = upload.geometry.sourceRect;
|
| + IntSize destOffset = upload.geometry.destOffset;
|
| +
|
| + texture->acquireBackingTexture(resourceProvider);
|
| + ASSERT(texture->haveBackingTexture());
|
| +
|
| + ASSERT(resourceProvider->resourceType(texture->resourceId()) ==
|
| + CCResourceProvider::GLTexture);
|
| +
|
| + WebGraphicsContext3D* paintContext = CCProxy::hasImplThread() ?
|
| + WebSharedGraphicsContext3D::compositorThreadContext() :
|
| + WebSharedGraphicsContext3D::mainThreadContext();
|
| + GrContext* paintGrContext = CCProxy::hasImplThread() ?
|
| + WebSharedGraphicsContext3D::compositorThreadGrContext() :
|
| + WebSharedGraphicsContext3D::mainThreadGrContext();
|
| +
|
| + // Flush the context in which the backing texture is created so that it
|
| + // is available in other shared contexts. It is important to do here
|
| + // because the backing texture is created in one context while it is
|
| + // being written to in another.
|
| + resourceProvider->flush();
|
| + CCResourceProvider::ScopedWriteLockGL lock(
|
| + resourceProvider, texture->resourceId());
|
| +
|
| + // Make sure ganesh uses the correct GL context.
|
| + paintContext->makeContextCurrent();
|
| +
|
| + // Create an accelerated canvas to draw on.
|
| + OwnPtr<SkCanvas> canvas = createAcceleratedCanvas(
|
| + paintGrContext, texture->size(), lock.textureId());
|
| +
|
| + // The compositor expects the textures to be upside-down so it can flip
|
| + // the final composited image. Ganesh renders the image upright so we
|
| + // need to do a y-flip.
|
| + canvas->translate(0.0, texture->size().height());
|
| + canvas->scale(1.0, -1.0);
|
| + // Clip to the destination on the texture that must be updated.
|
| + canvas->clipRect(SkRect::MakeXYWH(destOffset.width(),
|
| + destOffset.height(),
|
| + sourceRect.width(),
|
| + sourceRect.height()));
|
| + // Translate the origin of pictureRect to destOffset.
|
| + // Note that destOffset is defined relative to sourceRect.
|
| + canvas->translate(
|
| + pictureRect.x() - sourceRect.x() + destOffset.width(),
|
| + pictureRect.y() - sourceRect.y() + destOffset.height());
|
| + canvas->drawPicture(*upload.picture);
|
| +
|
| + // Flush ganesh context so that all the rendered stuff appears on the
|
| + // texture.
|
| + paintGrContext->flush();
|
| +
|
| + // Flush the GL context so rendering results from this context are
|
| + // visible in the compositor's context.
|
| + paintContext->flush();
|
| + }
|
|
|
| if (isFullUpload)
|
| endQuery();
|
|
|