1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
// Copyright 2016 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 "platform/graphics/SkiaTextureHolder.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "platform/CrossThreadFunctional.h"
#include "platform/graphics/MailboxTextureHolder.h"
#include "platform/graphics/gpu/SharedGpuContext.h"
#include "public/platform/Platform.h"
#include "skia/ext/texture_handle.h"
#include "third_party/skia/include/gpu/GrContext.h"
namespace blink {
namespace {
void releaseImage(sk_sp<SkImage>&& image,
std::unique_ptr<gpu::SyncToken>&& syncToken) {
if (SharedGpuContext::isValid() && syncToken->HasData())
SharedGpuContext::gl()->WaitSyncTokenCHROMIUM(syncToken->GetData());
image.reset();
}
} // namespace
SkiaTextureHolder::SkiaTextureHolder(sk_sp<SkImage> image)
: m_image(std::move(image)),
m_sharedContextId(SharedGpuContext::contextId()) {}
SkiaTextureHolder::SkiaTextureHolder(
std::unique_ptr<TextureHolder> textureHolder) {
DCHECK(textureHolder->isMailboxTextureHolder());
const gpu::Mailbox mailbox = textureHolder->mailbox();
const gpu::SyncToken syncToken = textureHolder->syncToken();
const IntSize mailboxSize = textureHolder->size();
gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl();
GrContext* sharedGrContext = SharedGpuContext::gr();
DCHECK(sharedGL &&
sharedGrContext); // context isValid already checked in callers
sharedGL->WaitSyncTokenCHROMIUM(syncToken.GetConstData());
GLuint sharedContextTextureId =
sharedGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
GrGLTextureInfo textureInfo;
textureInfo.fTarget = GL_TEXTURE_2D;
textureInfo.fID = sharedContextTextureId;
GrBackendTextureDesc backendTexture;
backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
backendTexture.fWidth = mailboxSize.width();
backendTexture.fHeight = mailboxSize.height();
backendTexture.fConfig = kSkia8888_GrPixelConfig;
backendTexture.fTextureHandle =
skia::GrGLTextureInfoToGrBackendObject(textureInfo);
sk_sp<SkImage> newImage =
SkImage::MakeFromAdoptedTexture(sharedGrContext, backendTexture);
releaseImageThreadSafe();
m_image = newImage;
m_sharedContextId = SharedGpuContext::contextId();
}
SkiaTextureHolder::~SkiaTextureHolder() {
releaseImageThreadSafe();
}
unsigned SkiaTextureHolder::sharedContextId() {
return m_sharedContextId;
}
void SkiaTextureHolder::releaseImageThreadSafe() {
// If m_image belongs to a GrContext that is on another thread, it
// must be released on that thread.
if (textureThreadTaskRunner() && m_image && wasTransferred() &&
SharedGpuContext::isValid()) {
gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl();
std::unique_ptr<gpu::SyncToken> releaseSyncToken(new gpu::SyncToken);
const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM();
sharedGL->Flush();
sharedGL->GenSyncTokenCHROMIUM(fenceSync, releaseSyncToken->GetData());
textureThreadTaskRunner()->postTask(
BLINK_FROM_HERE,
crossThreadBind(&releaseImage, WTF::passed(std::move(m_image)),
WTF::passed(std::move(releaseSyncToken))));
}
m_image = nullptr;
setWasTransferred(false);
setTextureThreadTaskRunner(nullptr);
}
} // namespace blink
|