v8 js代码与canvas的绘制
v8::MaybeLocal<v8::Value> maybe_result;
if (V8ScriptRunner::CompileScript(script_state, *classic_script,
compile_options, no_cache_reason,
host_defined_options)
.ToLocal(&script)) {
maybe_result = V8ScriptRunner::RunCompiledScript(
isolate, script, host_defined_options, execution_context);
probe::DidProduceCompilationCache(
probe::ToCoreProbeSink(execution_context), *classic_script, script);
html:
查看代码
<!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"> <script> var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.moveTo(0,0); ctx.lineTo(200,100); ctx.stroke(); </script> </body> </html>
对与 canvas context的 ctx.stroke();语句执行断点:(第一次会 textrueLayer 创建,以后直接获取)
scoped_refptr<TextureLayer> TextureLayer::CreateForMailbox( TextureLayerClient* client) { return scoped_refptr<TextureLayer>(new TextureLayer(client)); }
创建后返回 paintCanvas:
查看代码
cc::PaintCanvas* CanvasRenderingContext2D::GetOrCreatePaintCanvas() { if (UNLIKELY(isContextLost())) return nullptr; if (LIKELY(canvas()->GetOrCreateCanvas2DLayerBridge())) return canvas()->GetCanvas2DLayerBridge()->GetPaintCanvas(); return nullptr; }
drawStroke,就是调用内部的drawInnerPath:
void BaseRenderingContext2D::stroke() { if (identifiability_study_helper_.ShouldUpdateBuilder()) { identifiability_study_helper_.UpdateBuilder(CanvasOps::kStroke); } DrawPathInternal(path_, CanvasRenderingContext2DState::kStrokePaintType, SkPathFillType::kWinding, UsePaintCache::kDisabled); } void BaseRenderingContext2D::DrawPathInternal( const Path& path, CanvasRenderingContext2DState::PaintType paint_type, SkPathFillType fill_type, UsePaintCache use_paint_cache) { if (path.IsEmpty()) return; SkPath sk_path = path.GetSkPath(); gfx::RectF bounds(path.BoundingRect()); if (std::isnan(bounds.x()) || std::isnan(bounds.y()) || std::isnan(bounds.width()) || std::isnan(bounds.height())) return; sk_path.setFillType(fill_type); if (paint_type == CanvasRenderingContext2DState::kStrokePaintType) InflateStrokeRect(bounds); if (!GetOrCreatePaintCanvas()) return; Draw<OverdrawOp::kNone>( [sk_path, use_paint_cache](cc::PaintCanvas* c, const cc::PaintFlags* flags) // draw lambda { c->drawPath(sk_path, *flags, use_paint_cache); }, [](const SkIRect& rect) // overdraw test lambda { return false; }, gfx::RectFToSkRect(bounds), paint_type, GetState().HasPattern(paint_type) ? CanvasRenderingContext2DState::kNonOpaqueImage : CanvasRenderingContext2DState::kNoImage, CanvasPerformanceMonitor::DrawType::kPath); }
最终走到draw模板函数
template <BaseRenderingContext2D::OverdrawOp CurrentOverdrawOp, typename DrawFunc, typename DrawCoversClipBoundsFunc> void BaseRenderingContext2D::Draw( const DrawFunc& draw_func, const DrawCoversClipBoundsFunc& draw_covers_clip_bounds, const SkRect& bounds, CanvasRenderingContext2DState::PaintType paint_type, CanvasRenderingContext2DState::ImageType image_type, CanvasPerformanceMonitor::DrawType draw_type) { if (!IsTransformInvertible()) return; SkIRect clip_bounds; cc::PaintCanvas* paint_canvas = GetOrCreatePaintCanvas(); if (!paint_canvas || !paint_canvas->getDeviceClipBounds(&clip_bounds)) return; if (UNLIKELY(GetState().IsFilterUnresolved())) { // Resolving a filter requires allocating garbage-collected objects. PostDeferrableAction(WTF::Bind( &BaseRenderingContext2D::DrawInternal<CurrentOverdrawOp, DrawFunc, DrawCoversClipBoundsFunc>, WrapPersistent(this), draw_func, draw_covers_clip_bounds, bounds, paint_type, image_type, clip_bounds, draw_type)); } else { DrawInternal<CurrentOverdrawOp, DrawFunc, DrawCoversClipBoundsFunc>( draw_func, draw_covers_clip_bounds, bounds, paint_type, image_type, clip_bounds, draw_type); } }
走到drawInternal
template <BaseRenderingContext2D::OverdrawOp CurrentOverdrawOp, typename DrawFunc, typename DrawCoversClipBoundsFunc> void BaseRenderingContext2D::DrawInternal( const DrawFunc& draw_func, const DrawCoversClipBoundsFunc& draw_covers_clip_bounds, const SkRect& bounds, CanvasRenderingContext2DState::PaintType paint_type, CanvasRenderingContext2DState::ImageType image_type, const SkIRect& clip_bounds, CanvasPerformanceMonitor::DrawType draw_type) { const CanvasRenderingContext2DState& state = GetState(); SkBlendMode global_composite = state.GlobalComposite(); if (IsFullCanvasCompositeMode(global_composite) || StateHasFilter() || (state.ShouldDrawShadows() && ShouldUseDropShadowPaintFilter(paint_type, image_type))) { CompositedDraw(draw_func, GetPaintCanvasForDraw(clip_bounds, draw_type), paint_type, image_type); } else if (global_composite == SkBlendMode::kSrc) { ClearCanvasForSrcCompositeOp(); // Takes care of CheckOverdraw() const cc::PaintFlags* flags = state.GetFlags(paint_type, kDrawForegroundOnly, image_type); draw_func(GetPaintCanvasForDraw(clip_bounds, draw_type), flags); } else { SkIRect dirty_rect; if (ComputeDirtyRect(gfx::SkRectToRectF(bounds), clip_bounds, &dirty_rect)) { const cc::PaintFlags* flags = state.GetFlags(paint_type, kDrawShadowAndForeground, image_type); if (paint_type != CanvasRenderingContext2DState::kStrokePaintType && draw_covers_clip_bounds(clip_bounds)) { // Because CurrentOverdrawOp is a template argument the following branch // is optimized-out at compile time. if (CurrentOverdrawOp != OverdrawOp::kNone) { CheckOverdraw(bounds, flags, image_type, CurrentOverdrawOp); } } draw_func(GetPaintCanvasForDraw(dirty_rect, draw_type), flags); }
canvas限制相关:
std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::CreateSharedImageProvider( const SkImageInfo& info, cc::PaintFlags::FilterQuality filter_quality, ShouldInitialize should_initialize, base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper, RasterMode raster_mode, bool is_origin_top_left, uint32_t shared_image_usage_flags) { // IsGpuCompositingEnabled can re-create the context if it has been lost, do // this up front so that we can fail early and not expose ourselves to // use after free bugs (crbug.com/1126424) const bool is_gpu_compositing_enabled = SharedGpuContext::IsGpuCompositingEnabled(); // If the context is lost we don't want to re-create it here, the resulting // resource provider would be invalid anyway if (!context_provider_wrapper || context_provider_wrapper->ContextProvider()->IsContextLost()) return nullptr; const auto& capabilities = context_provider_wrapper->ContextProvider()->GetCapabilities(); bool skia_use_dawn = raster_mode == RasterMode::kGPU && base::FeatureList::IsEnabled(blink::features::kDawn2dCanvas); // TODO(senorblanco): once Dawn reports maximum texture size, Dawn Canvas // should respect it. http://crbug.com/1082760 if (!skia_use_dawn && (info.width() < 1 || info.height() < 1 || info.width() > capabilities.max_texture_size || info.height() > capabilities.max_texture_size)) { return nullptr; } const bool is_accelerated = raster_mode == RasterMode::kGPU; SkImageInfo adjusted_info = info; // TODO(https://crbug.com/1210946): Pass in info as is for all cases. // Overriding the info to use RGBA instead of N32 is needed because code // elsewhere assumes RGBA. OTOH the software path seems to be assuming N32 // somewhere in the later pipeline but for offscreen canvas only. if (!(shared_image_usage_flags & gpu::SHARED_IMAGE_USAGE_WEBGPU)) { adjusted_info = adjusted_info.makeColorType( is_accelerated && info.colorType() != kRGBA_F16_SkColorType ? kRGBA_8888_SkColorType : info.colorType()); } const bool is_gpu_memory_buffer_image_allowed = is_gpu_compositing_enabled && IsGMBAllowed(adjusted_info, capabilities) && Platform::Current()->GetGpuMemoryBufferManager(); if (raster_mode == RasterMode::kCPU && !is_gpu_memory_buffer_image_allowed) return nullptr; // If we cannot use overlay, we have to remove the scanout flag and the // concurrent read write flag. // TODO(junov, vasilyt): capabilities.texture_storage_image is being used // as a proxy for determining whether SHARED_IMAGE_USAGE_SCANOUT is supported. // it would be preferable to have a dedicated capability bit for this. if (!is_gpu_memory_buffer_image_allowed || (is_accelerated && !capabilities.texture_storage_image)) { shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE; shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_SCANOUT; } #if BUILDFLAG(IS_MAC) if ((shared_image_usage_flags & gpu::SHARED_IMAGE_USAGE_SCANOUT) && is_accelerated && adjusted_info.colorType() == kRGBA_8888_SkColorType) { // GPU-accelerated scannout usage on Mac uses IOSurface. Must switch from // RGBA_8888 to BGRA_8888 in that case. adjusted_info = adjusted_info.makeColorType(kBGRA_8888_SkColorType); } #endif auto provider = std::make_unique<CanvasResourceProviderSharedImage>( adjusted_info, filter_quality, context_provider_wrapper, is_origin_top_left, is_accelerated, skia_use_dawn, shared_image_usage_flags); if (provider->IsValid()) { if (should_initialize == CanvasResourceProvider::ShouldInitialize::kCallClear) provider->Clear(); return provider; } return nullptr; }
分类:
chromium笔记
标签:
canvas
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2020-03-23 Getting Around the Chromium Source Code Directory Structure
2020-03-23 The old instructions for getting the code
2020-03-23 host 生成 github上README.md图片显示不出来
2020-03-23 electron chromium源码下载 2020 84
2020-03-23 Checking out and building Chromium on Linux
2020-03-23 chromium在windows上的编译 构建 Checking out and Building Chromium for Windows
2014-03-23 speech