Bug 1238755 - Avoid a copy when uploading the BasicCompositor result to a texture. r?mattwoodrow
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -313,16 +313,17 @@ public:
const Matrix4x4& aTransform = Matrix4x4());
static LayoutDeviceIntSize TextureSizeForSize(
const LayoutDeviceIntSize& aSize);
protected:
RefPtr<gfx::DrawTarget> mUpdateDrawTarget;
+ UniquePtr<unsigned char[]> mUpdateDrawTargetData;
GLContext* mGLContext;
LayoutDeviceIntRegion mUpdateRegion;
LayoutDeviceIntSize mUsedSize;
LayoutDeviceIntSize mBufferSize;
LayoutDeviceIntSize mTextureSize;
GLuint mTexture;
bool mInUpdate;
};
@@ -2931,19 +2932,24 @@ RectTextureImage::BeginUpdate(const Layo
if (mUpdateRegion.IsEmpty()) {
return nullptr;
}
LayoutDeviceIntSize neededBufferSize = TextureSizeForSize(mUsedSize);
if (!mUpdateDrawTarget || mBufferSize != neededBufferSize) {
gfx::IntSize size(neededBufferSize.width, neededBufferSize.height);
+ mUpdateDrawTarget = nullptr;
+ mUpdateDrawTargetData = nullptr;
+ int32_t stride = size.width * 4;
+ mUpdateDrawTargetData = MakeUnique<unsigned char[]>(stride * size.height);
mUpdateDrawTarget =
- gfx::Factory::CreateDrawTarget(gfx::BackendType::COREGRAPHICS, size,
- gfx::SurfaceFormat::B8G8R8A8);
+ gfx::Factory::CreateDrawTargetForData(gfx::BackendType::COREGRAPHICS,
+ mUpdateDrawTargetData.get(), size,
+ stride, gfx::SurfaceFormat::B8G8R8A8);
mBufferSize = neededBufferSize;
}
mInUpdate = true;
RefPtr<gfx::DrawTarget> drawTarget = mUpdateDrawTarget;
return drawTarget.forget();
}
@@ -2968,31 +2974,31 @@ RectTextureImage::EndUpdate(bool aKeepSu
mTextureSize = mBufferSize;
}
if (overwriteTexture || !CanUploadSubtextures()) {
updateRegion =
LayoutDeviceIntRect(LayoutDeviceIntPoint(0, 0), mTextureSize);
}
- RefPtr<gfx::SourceSurface> snapshot = mUpdateDrawTarget->Snapshot();
- RefPtr<gfx::DataSourceSurface> dataSnapshot = snapshot->GetDataSurface();
-
- UploadSurfaceToTexture(mGLContext,
- dataSnapshot,
- updateRegion.ToUnknownRegion(),
- mTexture,
- overwriteTexture,
- updateRegion.GetBounds().TopLeft().ToUnknownPoint(),
- false,
- LOCAL_GL_TEXTURE0,
- LOCAL_GL_TEXTURE_RECTANGLE_ARB);
+ gfx::IntPoint srcPoint = updateRegion.GetBounds().TopLeft().ToUnknownPoint();
+ unsigned char* data = mUpdateDrawTargetData.get();
+ int32_t stride = mBufferSize.width * 4;
+ gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8;
+ data += srcPoint.y * stride + srcPoint.x * 4;
+
+ UploadImageDataToTexture(mGLContext, data, stride, format,
+ updateRegion.ToUnknownRegion(), mTexture,
+ overwriteTexture, false,
+ LOCAL_GL_TEXTURE0,
+ LOCAL_GL_TEXTURE_RECTANGLE_ARB);
if (!aKeepSurface) {
mUpdateDrawTarget = nullptr;
+ mUpdateDrawTargetData = nullptr;
}
mInUpdate = false;
}
void
RectTextureImage::UpdateFromCGContext(const LayoutDeviceIntSize& aNewSize,
const LayoutDeviceIntRegion& aDirtyRegion,