| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
| 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 contextTypeHistogram.count(contextType); | 251 contextTypeHistogram.count(contextType); |
| 252 } | 252 } |
| 253 | 253 |
| 254 contextType = CanvasRenderingContext::resolveContextTypeAliases(contextType); | 254 contextType = CanvasRenderingContext::resolveContextTypeAliases(contextType); |
| 255 | 255 |
| 256 CanvasRenderingContextFactory* factory = | 256 CanvasRenderingContextFactory* factory = |
| 257 getRenderingContextFactory(contextType); | 257 getRenderingContextFactory(contextType); |
| 258 if (!factory) | 258 if (!factory) |
| 259 return nullptr; | 259 return nullptr; |
| 260 | 260 |
| 261 // FIXME - The code depends on the context not going away once created, to pre
vent JS from | 261 // FIXME - The code depends on the context not going away once created, to |
| 262 // seeing a dangling pointer. So for now we will disallow the context from bei
ng changed | 262 // prevent JS from seeing a dangling pointer. So for now we will disallow the |
| 263 // once it is created. | 263 // context from being changed once it is created. |
| 264 if (m_context) { | 264 if (m_context) { |
| 265 if (m_context->getContextType() == contextType) | 265 if (m_context->getContextType() == contextType) |
| 266 return m_context.get(); | 266 return m_context.get(); |
| 267 | 267 |
| 268 factory->onError(this, | 268 factory->onError(this, |
| 269 "Canvas has an existing context of a different type"); | 269 "Canvas has an existing context of a different type"); |
| 270 return nullptr; | 270 return nullptr; |
| 271 } | 271 } |
| 272 | 272 |
| 273 m_context = factory->create(this, attributes, document()); | 273 m_context = factory->create(this, attributes, document()); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 | 342 |
| 343 m_numFramesSinceLastRenderingModeSwitch++; | 343 m_numFramesSinceLastRenderingModeSwitch++; |
| 344 if (RuntimeEnabledFeatures:: | 344 if (RuntimeEnabledFeatures:: |
| 345 enableCanvas2dDynamicRenderingModeSwitchingEnabled() && | 345 enableCanvas2dDynamicRenderingModeSwitchingEnabled() && |
| 346 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled()) { | 346 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled()) { |
| 347 if (m_context->is2d() && buffer() && buffer()->isAccelerated() && | 347 if (m_context->is2d() && buffer() && buffer()->isAccelerated() && |
| 348 m_numFramesSinceLastRenderingModeSwitch >= | 348 m_numFramesSinceLastRenderingModeSwitch >= |
| 349 ExpensiveCanvasHeuristicParameters::MinFramesBeforeSwitch && | 349 ExpensiveCanvasHeuristicParameters::MinFramesBeforeSwitch && |
| 350 !m_pendingRenderingModeSwitch) { | 350 !m_pendingRenderingModeSwitch) { |
| 351 if (!m_context->isAccelerationOptimalForCanvasContent()) { | 351 if (!m_context->isAccelerationOptimalForCanvasContent()) { |
| 352 // The switch must be done asynchronously in order to avoid switching du
ring the paint invalidation step. | 352 // The switch must be done asynchronously in order to avoid switching |
| 353 // during the paint invalidation step. |
| 353 Platform::current()->currentThread()->getWebTaskRunner()->postTask( | 354 Platform::current()->currentThread()->getWebTaskRunner()->postTask( |
| 354 BLINK_FROM_HERE, | 355 BLINK_FROM_HERE, |
| 355 WTF::bind( | 356 WTF::bind( |
| 356 [](WeakPtr<ImageBuffer> buffer) { | 357 [](WeakPtr<ImageBuffer> buffer) { |
| 357 if (buffer) { | 358 if (buffer) { |
| 358 buffer->disableAcceleration(); | 359 buffer->disableAcceleration(); |
| 359 } | 360 } |
| 360 }, | 361 }, |
| 361 m_imageBuffer->m_weakPtrFactory.createWeakPtr())); | 362 m_imageBuffer->m_weakPtrFactory.createWeakPtr())); |
| 362 m_numFramesSinceLastRenderingModeSwitch = 0; | 363 m_numFramesSinceLastRenderingModeSwitch = 0; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 389 didFinalizeFrame(); | 390 didFinalizeFrame(); |
| 390 } else { | 391 } else { |
| 391 DCHECK(hasImageBuffer()); | 392 DCHECK(hasImageBuffer()); |
| 392 FloatRect srcRect(0, 0, size().width(), size().height()); | 393 FloatRect srcRect(0, 0, size().width(), size().height()); |
| 393 m_dirtyRect.intersect(srcRect); | 394 m_dirtyRect.intersect(srcRect); |
| 394 LayoutBox* lb = layoutBox(); | 395 LayoutBox* lb = layoutBox(); |
| 395 if (lb) { | 396 if (lb) { |
| 396 FloatRect mappedDirtyRect = | 397 FloatRect mappedDirtyRect = |
| 397 mapRect(m_dirtyRect, srcRect, FloatRect(lb->contentBoxRect())); | 398 mapRect(m_dirtyRect, srcRect, FloatRect(lb->contentBoxRect())); |
| 398 if (m_context->isAccelerated()) { | 399 if (m_context->isAccelerated()) { |
| 399 // Accelerated 2D canvases need the dirty rect to be expressed relative
to the | 400 // Accelerated 2D canvases need the dirty rect to be expressed relative |
| 400 // content box, as opposed to the layout box. | 401 // to the content box, as opposed to the layout box. |
| 401 mappedDirtyRect.move(-lb->contentBoxOffset()); | 402 mappedDirtyRect.move(-lb->contentBoxOffset()); |
| 402 } | 403 } |
| 403 m_imageBuffer->finalizeFrame(mappedDirtyRect); | 404 m_imageBuffer->finalizeFrame(mappedDirtyRect); |
| 404 } else { | 405 } else { |
| 405 m_imageBuffer->finalizeFrame(m_dirtyRect); | 406 m_imageBuffer->finalizeFrame(m_dirtyRect); |
| 406 } | 407 } |
| 407 } | 408 } |
| 408 DCHECK(m_dirtyRect.isEmpty()); | 409 DCHECK(m_dirtyRect.isEmpty()); |
| 409 } | 410 } |
| 410 | 411 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 424 int h = getAttribute(heightAttr).toInt(&ok); | 425 int h = getAttribute(heightAttr).toInt(&ok); |
| 425 if (!ok || h < 0) | 426 if (!ok || h < 0) |
| 426 h = DefaultHeight; | 427 h = DefaultHeight; |
| 427 | 428 |
| 428 if (m_context && m_context->is2d()) | 429 if (m_context && m_context->is2d()) |
| 429 m_context->reset(); | 430 m_context->reset(); |
| 430 | 431 |
| 431 IntSize oldSize = size(); | 432 IntSize oldSize = size(); |
| 432 IntSize newSize(w, h); | 433 IntSize newSize(w, h); |
| 433 | 434 |
| 434 // If the size of an existing buffer matches, we can just clear it instead of
reallocating. | 435 // If the size of an existing buffer matches, we can just clear it instead of |
| 435 // This optimization is only done for 2D canvases for now. | 436 // reallocating. This optimization is only done for 2D canvases for now. |
| 436 if (hadImageBuffer && oldSize == newSize && m_context && m_context->is2d() && | 437 if (hadImageBuffer && oldSize == newSize && m_context && m_context->is2d() && |
| 437 !buffer()->isRecording()) { | 438 !buffer()->isRecording()) { |
| 438 if (!m_imageBufferIsClear) { | 439 if (!m_imageBufferIsClear) { |
| 439 m_imageBufferIsClear = true; | 440 m_imageBufferIsClear = true; |
| 440 m_context->clearRect(0, 0, width(), height()); | 441 m_context->clearRect(0, 0, width(), height()); |
| 441 } | 442 } |
| 442 return; | 443 return; |
| 443 } | 444 } |
| 444 | 445 |
| 445 setSurfaceSize(newSize); | 446 setSurfaceSize(newSize); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 sk_sp<SkImage> image = sourceImage->imageForCurrentFrame(); | 498 sk_sp<SkImage> image = sourceImage->imageForCurrentFrame(); |
| 498 for (CanvasDrawListener* listener : m_listeners) { | 499 for (CanvasDrawListener* listener : m_listeners) { |
| 499 if (listener->needsNewFrame()) { | 500 if (listener->needsNewFrame()) { |
| 500 listener->sendNewFrame(image); | 501 listener->sendNewFrame(image); |
| 501 } | 502 } |
| 502 } | 503 } |
| 503 } | 504 } |
| 504 } | 505 } |
| 505 | 506 |
| 506 void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r) { | 507 void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r) { |
| 507 // FIXME: crbug.com/438240; there is a bug with the new CSS blending and compo
siting feature. | 508 // FIXME: crbug.com/438240; there is a bug with the new CSS blending and |
| 509 // compositing feature. |
| 508 if (!m_context) | 510 if (!m_context) |
| 509 return; | 511 return; |
| 510 | 512 |
| 511 const ComputedStyle* style = ensureComputedStyle(); | 513 const ComputedStyle* style = ensureComputedStyle(); |
| 512 SkFilterQuality filterQuality = | 514 SkFilterQuality filterQuality = |
| 513 (style && style->imageRendering() == ImageRenderingPixelated) | 515 (style && style->imageRendering() == ImageRenderingPixelated) |
| 514 ? kNone_SkFilterQuality | 516 ? kNone_SkFilterQuality |
| 515 : kLow_SkFilterQuality; | 517 : kLow_SkFilterQuality; |
| 516 | 518 |
| 517 if (is3D()) { | 519 if (is3D()) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 toDataURLImageFormatHistogram.count(imageFormat); | 620 toDataURLImageFormatHistogram.count(imageFormat); |
| 619 } else if (encodeReason == EncodeReasonToBlobCallback) { | 621 } else if (encodeReason == EncodeReasonToBlobCallback) { |
| 620 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 622 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 621 EnumerationHistogram, toBlobCallbackImageFormatHistogram, | 623 EnumerationHistogram, toBlobCallbackImageFormatHistogram, |
| 622 new EnumerationHistogram( | 624 new EnumerationHistogram( |
| 623 "Canvas.RequestedImageMimeTypes_toBlobCallback", | 625 "Canvas.RequestedImageMimeTypes_toBlobCallback", |
| 624 NumberOfRequestedImageMimeTypes)); | 626 NumberOfRequestedImageMimeTypes)); |
| 625 toBlobCallbackImageFormatHistogram.count(imageFormat); | 627 toBlobCallbackImageFormatHistogram.count(imageFormat); |
| 626 } | 628 } |
| 627 | 629 |
| 628 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this m
ethod to be used on a worker thread). | 630 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this |
| 631 // method to be used on a worker thread). |
| 629 if (!MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType)) | 632 if (!MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType)) |
| 630 lowercaseMimeType = DefaultMimeType; | 633 lowercaseMimeType = DefaultMimeType; |
| 631 return lowercaseMimeType; | 634 return lowercaseMimeType; |
| 632 } | 635 } |
| 633 | 636 |
| 634 const AtomicString HTMLCanvasElement::imageSourceURL() const { | 637 const AtomicString HTMLCanvasElement::imageSourceURL() const { |
| 635 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); | 638 return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); |
| 636 } | 639 } |
| 637 | 640 |
| 638 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const { | 641 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const { |
| 639 DCHECK(m_context && | 642 DCHECK(m_context && |
| 640 m_context->is2d()); // This function is called by the 2d context | 643 m_context->is2d()); // This function is called by the 2d context |
| 641 if (buffer()) | 644 if (buffer()) |
| 642 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); | 645 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); |
| 643 } | 646 } |
| 644 | 647 |
| 645 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, | 648 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, |
| 646 SnapshotReason reason) const { | 649 SnapshotReason reason) const { |
| 647 ImageData* imageData; | 650 ImageData* imageData; |
| 648 if (is3D()) { | 651 if (is3D()) { |
| 649 // Get non-premultiplied data because of inaccurate premultiplied alpha conv
ersion of buffer()->toDataURL(). | 652 // Get non-premultiplied data because of inaccurate premultiplied alpha |
| 653 // conversion of buffer()->toDataURL(). |
| 650 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); | 654 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); |
| 651 if (imageData) | 655 if (imageData) |
| 652 return imageData; | 656 return imageData; |
| 653 | 657 |
| 654 m_context->paintRenderingResultsToCanvas(sourceBuffer); | 658 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
| 655 imageData = ImageData::create(m_size); | 659 imageData = ImageData::create(m_size); |
| 656 if (imageData && hasImageBuffer()) { | 660 if (imageData && hasImageBuffer()) { |
| 657 sk_sp<SkImage> snapshot = | 661 sk_sp<SkImage> snapshot = |
| 658 buffer()->newSkImageSnapshot(PreferNoAcceleration, reason); | 662 buffer()->newSkImageSnapshot(PreferNoAcceleration, reason); |
| 659 if (snapshot) { | 663 if (snapshot) { |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 if (m_context && !m_context->is2d()) | 868 if (m_context && !m_context->is2d()) |
| 865 return false; | 869 return false; |
| 866 | 870 |
| 867 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) | 871 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) |
| 868 return false; | 872 return false; |
| 869 | 873 |
| 870 if (!RuntimeEnabledFeatures::accelerated2dCanvasEnabled()) | 874 if (!RuntimeEnabledFeatures::accelerated2dCanvasEnabled()) |
| 871 return false; | 875 return false; |
| 872 | 876 |
| 873 // The following is necessary for handling the special case of canvases in the | 877 // The following is necessary for handling the special case of canvases in the |
| 874 // dev tools overlay, which run in a process that supports accelerated 2d canv
as | 878 // dev tools overlay, which run in a process that supports accelerated 2d |
| 875 // but in a special compositing context that does not. | 879 // canvas but in a special compositing context that does not. |
| 876 if (layoutBox() && !layoutBox()->hasAcceleratedCompositing()) | 880 if (layoutBox() && !layoutBox()->hasAcceleratedCompositing()) |
| 877 return false; | 881 return false; |
| 878 | 882 |
| 879 CheckedNumeric<int> checkedCanvasPixelCount = size.width(); | 883 CheckedNumeric<int> checkedCanvasPixelCount = size.width(); |
| 880 checkedCanvasPixelCount *= size.height(); | 884 checkedCanvasPixelCount *= size.height(); |
| 881 if (!checkedCanvasPixelCount.IsValid()) | 885 if (!checkedCanvasPixelCount.IsValid()) |
| 882 return false; | 886 return false; |
| 883 int canvasPixelCount = checkedCanvasPixelCount.ValueOrDie(); | 887 int canvasPixelCount = checkedCanvasPixelCount.ValueOrDie(); |
| 884 | 888 |
| 885 if (RuntimeEnabledFeatures::displayList2dCanvasEnabled()) { | 889 if (RuntimeEnabledFeatures::displayList2dCanvasEnabled()) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 sk_sp<SkColorSpace> colorSpace) { | 1013 sk_sp<SkColorSpace> colorSpace) { |
| 1010 if (shouldUseDisplayList(deviceSize)) { | 1014 if (shouldUseDisplayList(deviceSize)) { |
| 1011 auto surface = wrapUnique(new RecordingImageBufferSurface( | 1015 auto surface = wrapUnique(new RecordingImageBufferSurface( |
| 1012 deviceSize, wrapUnique(new UnacceleratedSurfaceFactory), opacityMode, | 1016 deviceSize, wrapUnique(new UnacceleratedSurfaceFactory), opacityMode, |
| 1013 colorSpace)); | 1017 colorSpace)); |
| 1014 if (surface->isValid()) { | 1018 if (surface->isValid()) { |
| 1015 CanvasMetrics::countCanvasContextUsage( | 1019 CanvasMetrics::countCanvasContextUsage( |
| 1016 CanvasMetrics::DisplayList2DCanvasImageBufferCreated); | 1020 CanvasMetrics::DisplayList2DCanvasImageBufferCreated); |
| 1017 return std::move(surface); | 1021 return std::move(surface); |
| 1018 } | 1022 } |
| 1019 // We fallback to a non-display-list surface without recording a metric here
. | 1023 // We fallback to a non-display-list surface without recording a metric |
| 1024 // here. |
| 1020 } | 1025 } |
| 1021 | 1026 |
| 1022 auto surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory()); | 1027 auto surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory()); |
| 1023 auto surface = surfaceFactory->createSurface(deviceSize, opacityMode, | 1028 auto surface = surfaceFactory->createSurface(deviceSize, opacityMode, |
| 1024 std::move(colorSpace)); | 1029 std::move(colorSpace)); |
| 1025 if (surface->isValid()) { | 1030 if (surface->isValid()) { |
| 1026 CanvasMetrics::countCanvasContextUsage( | 1031 CanvasMetrics::countCanvasContextUsage( |
| 1027 CanvasMetrics::Unaccelerated2DCanvasImageBufferCreated); | 1032 CanvasMetrics::Unaccelerated2DCanvasImageBufferCreated); |
| 1028 return surface; | 1033 return surface; |
| 1029 } | 1034 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 m_didFailToCreateImageBuffer = false; | 1082 m_didFailToCreateImageBuffer = false; |
| 1078 | 1083 |
| 1079 updateExternallyAllocatedMemory(); | 1084 updateExternallyAllocatedMemory(); |
| 1080 | 1085 |
| 1081 if (is3D()) { | 1086 if (is3D()) { |
| 1082 // Early out for WebGL canvases | 1087 // Early out for WebGL canvases |
| 1083 return; | 1088 return; |
| 1084 } | 1089 } |
| 1085 | 1090 |
| 1086 m_imageBuffer->setClient(this); | 1091 m_imageBuffer->setClient(this); |
| 1087 // Enabling MSAA overrides a request to disable antialiasing. This is true reg
ardless of whether the | 1092 // Enabling MSAA overrides a request to disable antialiasing. This is true |
| 1088 // rendering mode is accelerated or not. For consistency, we don't want to app
ly AA in accelerated | 1093 // regardless of whether the rendering mode is accelerated or not. For |
| 1089 // canvases but not in unaccelerated canvases. | 1094 // consistency, we don't want to apply AA in accelerated canvases but not in |
| 1095 // unaccelerated canvases. |
| 1090 if (!msaaSampleCount && document().settings() && | 1096 if (!msaaSampleCount && document().settings() && |
| 1091 !document().settings()->antialiased2dCanvasEnabled()) | 1097 !document().settings()->antialiased2dCanvasEnabled()) |
| 1092 m_context->setShouldAntialias(false); | 1098 m_context->setShouldAntialias(false); |
| 1093 | 1099 |
| 1094 if (m_context) | 1100 if (m_context) |
| 1095 setNeedsCompositingUpdate(); | 1101 setNeedsCompositingUpdate(); |
| 1096 } | 1102 } |
| 1097 | 1103 |
| 1098 void HTMLCanvasElement::notifySurfaceInvalid() { | 1104 void HTMLCanvasElement::notifySurfaceInvalid() { |
| 1099 if (m_context && m_context->is2d()) | 1105 if (m_context && m_context->is2d()) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 if (is3D()) | 1139 if (is3D()) |
| 1134 checkedExternallyAllocatedMemory += | 1140 checkedExternallyAllocatedMemory += |
| 1135 m_context->externallyAllocatedBytesPerPixel(); | 1141 m_context->externallyAllocatedBytesPerPixel(); |
| 1136 | 1142 |
| 1137 checkedExternallyAllocatedMemory *= width(); | 1143 checkedExternallyAllocatedMemory *= width(); |
| 1138 checkedExternallyAllocatedMemory *= height(); | 1144 checkedExternallyAllocatedMemory *= height(); |
| 1139 intptr_t externallyAllocatedMemory = | 1145 intptr_t externallyAllocatedMemory = |
| 1140 checkedExternallyAllocatedMemory.ValueOrDefault( | 1146 checkedExternallyAllocatedMemory.ValueOrDefault( |
| 1141 std::numeric_limits<intptr_t>::max()); | 1147 std::numeric_limits<intptr_t>::max()); |
| 1142 | 1148 |
| 1143 // Subtracting two intptr_t that are known to be positive will never underflow
. | 1149 // Subtracting two intptr_t that are known to be positive will never |
| 1150 // underflow. |
| 1144 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( | 1151 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( |
| 1145 externallyAllocatedMemory - m_externallyAllocatedMemory); | 1152 externallyAllocatedMemory - m_externallyAllocatedMemory); |
| 1146 m_externallyAllocatedMemory = externallyAllocatedMemory; | 1153 m_externallyAllocatedMemory = externallyAllocatedMemory; |
| 1147 } | 1154 } |
| 1148 | 1155 |
| 1149 SkCanvas* HTMLCanvasElement::drawingCanvas() const { | 1156 SkCanvas* HTMLCanvasElement::drawingCanvas() const { |
| 1150 return buffer() ? m_imageBuffer->canvas() : nullptr; | 1157 return buffer() ? m_imageBuffer->canvas() : nullptr; |
| 1151 } | 1158 } |
| 1152 | 1159 |
| 1153 void HTMLCanvasElement::disableDeferral(DisableDeferralReason reason) const { | 1160 void HTMLCanvasElement::disableDeferral(DisableDeferralReason reason) const { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 } | 1283 } |
| 1277 | 1284 |
| 1278 if (!m_context) { | 1285 if (!m_context) { |
| 1279 *status = NormalSourceImageStatus; | 1286 *status = NormalSourceImageStatus; |
| 1280 return createTransparentImage(size()); | 1287 return createTransparentImage(size()); |
| 1281 } | 1288 } |
| 1282 | 1289 |
| 1283 sk_sp<SkImage> skImage; | 1290 sk_sp<SkImage> skImage; |
| 1284 if (m_context->is3d()) { | 1291 if (m_context->is3d()) { |
| 1285 // Because WebGL sources always require making a copy of the back buffer, we | 1292 // Because WebGL sources always require making a copy of the back buffer, we |
| 1286 // use paintRenderingResultsToCanvas instead of getImage in order to keep a
cached | 1293 // use paintRenderingResultsToCanvas instead of getImage in order to keep a |
| 1287 // copy of the backing in the canvas's ImageBuffer. | 1294 // cached copy of the backing in the canvas's ImageBuffer. |
| 1288 renderingContext()->paintRenderingResultsToCanvas(BackBuffer); | 1295 renderingContext()->paintRenderingResultsToCanvas(BackBuffer); |
| 1289 skImage = hasImageBuffer() | 1296 skImage = hasImageBuffer() |
| 1290 ? buffer()->newSkImageSnapshot(hint, reason) | 1297 ? buffer()->newSkImageSnapshot(hint, reason) |
| 1291 : createTransparentImage(size())->imageForCurrentFrame(); | 1298 : createTransparentImage(size())->imageForCurrentFrame(); |
| 1292 } else { | 1299 } else { |
| 1293 if (ExpensiveCanvasHeuristicParameters:: | 1300 if (ExpensiveCanvasHeuristicParameters:: |
| 1294 DisableAccelerationToAvoidReadbacks && | 1301 DisableAccelerationToAvoidReadbacks && |
| 1295 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled() && | 1302 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled() && |
| 1296 hint == PreferNoAcceleration && m_context->isAccelerated() && | 1303 hint == PreferNoAcceleration && m_context->isAccelerated() && |
| 1297 hasImageBuffer()) | 1304 hasImageBuffer()) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1345 | 1352 |
| 1346 bool HTMLCanvasElement::isOpaque() const { | 1353 bool HTMLCanvasElement::isOpaque() const { |
| 1347 return m_context && !m_context->creationAttributes().alpha(); | 1354 return m_context && !m_context->creationAttributes().alpha(); |
| 1348 } | 1355 } |
| 1349 | 1356 |
| 1350 bool HTMLCanvasElement::isSupportedInteractiveCanvasFallback( | 1357 bool HTMLCanvasElement::isSupportedInteractiveCanvasFallback( |
| 1351 const Element& element) { | 1358 const Element& element) { |
| 1352 if (!element.isDescendantOf(this)) | 1359 if (!element.isDescendantOf(this)) |
| 1353 return false; | 1360 return false; |
| 1354 | 1361 |
| 1355 // An element is a supported interactive canvas fallback element if it is one
of the following: | 1362 // An element is a supported interactive canvas fallback element if it is one |
| 1363 // of the following: |
| 1356 // https://html.spec.whatwg.org/multipage/scripting.html#supported-interactive
-canvas-fallback-element | 1364 // https://html.spec.whatwg.org/multipage/scripting.html#supported-interactive
-canvas-fallback-element |
| 1357 | 1365 |
| 1358 // An a element that represents a hyperlink and that does not have any img des
cendants. | 1366 // An a element that represents a hyperlink and that does not have any img |
| 1367 // descendants. |
| 1359 if (isHTMLAnchorElement(element)) | 1368 if (isHTMLAnchorElement(element)) |
| 1360 return !Traversal<HTMLImageElement>::firstWithin(element); | 1369 return !Traversal<HTMLImageElement>::firstWithin(element); |
| 1361 | 1370 |
| 1362 // A button element | 1371 // A button element |
| 1363 if (isHTMLButtonElement(element)) | 1372 if (isHTMLButtonElement(element)) |
| 1364 return true; | 1373 return true; |
| 1365 | 1374 |
| 1366 // An input element whose type attribute is in one of the Checkbox or Radio Bu
tton states. | 1375 // An input element whose type attribute is in one of the Checkbox or Radio |
| 1367 // An input element that is a button but its type attribute is not in the Imag
e Button state. | 1376 // Button states. An input element that is a button but its type attribute is |
| 1377 // not in the Image Button state. |
| 1368 if (isHTMLInputElement(element)) { | 1378 if (isHTMLInputElement(element)) { |
| 1369 const HTMLInputElement& inputElement = toHTMLInputElement(element); | 1379 const HTMLInputElement& inputElement = toHTMLInputElement(element); |
| 1370 if (inputElement.type() == InputTypeNames::checkbox || | 1380 if (inputElement.type() == InputTypeNames::checkbox || |
| 1371 inputElement.type() == InputTypeNames::radio || | 1381 inputElement.type() == InputTypeNames::radio || |
| 1372 inputElement.isTextButton()) | 1382 inputElement.isTextButton()) |
| 1373 return true; | 1383 return true; |
| 1374 } | 1384 } |
| 1375 | 1385 |
| 1376 // A select element with a multiple attribute or a display size greater than 1
. | 1386 // A select element with a "multiple" attribute or with a display size greater |
| 1387 // than 1. |
| 1377 if (isHTMLSelectElement(element)) { | 1388 if (isHTMLSelectElement(element)) { |
| 1378 const HTMLSelectElement& selectElement = toHTMLSelectElement(element); | 1389 const HTMLSelectElement& selectElement = toHTMLSelectElement(element); |
| 1379 if (selectElement.multiple() || selectElement.size() > 1) | 1390 if (selectElement.multiple() || selectElement.size() > 1) |
| 1380 return true; | 1391 return true; |
| 1381 } | 1392 } |
| 1382 | 1393 |
| 1383 // An option element that is in a list of options of a select element with a m
ultiple attribute or a display size greater than 1. | 1394 // An option element that is in a list of options of a select element with a |
| 1395 // "multiple" attribute or with a display size greater than 1. |
| 1384 if (isHTMLOptionElement(element) && element.parentNode() && | 1396 if (isHTMLOptionElement(element) && element.parentNode() && |
| 1385 isHTMLSelectElement(*element.parentNode())) { | 1397 isHTMLSelectElement(*element.parentNode())) { |
| 1386 const HTMLSelectElement& selectElement = | 1398 const HTMLSelectElement& selectElement = |
| 1387 toHTMLSelectElement(*element.parentNode()); | 1399 toHTMLSelectElement(*element.parentNode()); |
| 1388 if (selectElement.multiple() || selectElement.size() > 1) | 1400 if (selectElement.multiple() || selectElement.size() > 1) |
| 1389 return true; | 1401 return true; |
| 1390 } | 1402 } |
| 1391 | 1403 |
| 1392 // An element that would not be interactive content except for having the tabi
ndex attribute specified. | 1404 // An element that would not be interactive content except for having the |
| 1405 // tabindex attribute specified. |
| 1393 if (element.fastHasAttribute(HTMLNames::tabindexAttr)) | 1406 if (element.fastHasAttribute(HTMLNames::tabindexAttr)) |
| 1394 return true; | 1407 return true; |
| 1395 | 1408 |
| 1396 // A non-interactive table, caption, thead, tbody, tfoot, tr, td, or th elemen
t. | 1409 // A non-interactive table, caption, thead, tbody, tfoot, tr, td, or th |
| 1410 // element. |
| 1397 if (isHTMLTableElement(element) || | 1411 if (isHTMLTableElement(element) || |
| 1398 element.hasTagName(HTMLNames::captionTag) || | 1412 element.hasTagName(HTMLNames::captionTag) || |
| 1399 element.hasTagName(HTMLNames::theadTag) || | 1413 element.hasTagName(HTMLNames::theadTag) || |
| 1400 element.hasTagName(HTMLNames::tbodyTag) || | 1414 element.hasTagName(HTMLNames::tbodyTag) || |
| 1401 element.hasTagName(HTMLNames::tfootTag) || | 1415 element.hasTagName(HTMLNames::tfootTag) || |
| 1402 element.hasTagName(HTMLNames::trTag) || | 1416 element.hasTagName(HTMLNames::trTag) || |
| 1403 element.hasTagName(HTMLNames::tdTag) || | 1417 element.hasTagName(HTMLNames::tdTag) || |
| 1404 element.hasTagName(HTMLNames::thTag)) | 1418 element.hasTagName(HTMLNames::thTag)) |
| 1405 return true; | 1419 return true; |
| 1406 | 1420 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1425 mojom::blink::OffscreenCanvasSurfacePtr service; | 1439 mojom::blink::OffscreenCanvasSurfacePtr service; |
| 1426 Platform::current()->interfaceProvider()->getInterface( | 1440 Platform::current()->interfaceProvider()->getInterface( |
| 1427 mojo::GetProxy(&service)); | 1441 mojo::GetProxy(&service)); |
| 1428 m_surfaceLayerBridge = | 1442 m_surfaceLayerBridge = |
| 1429 wrapUnique(new CanvasSurfaceLayerBridge(std::move(service))); | 1443 wrapUnique(new CanvasSurfaceLayerBridge(std::move(service))); |
| 1430 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), | 1444 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), |
| 1431 this->height()); | 1445 this->height()); |
| 1432 } | 1446 } |
| 1433 | 1447 |
| 1434 } // namespace blink | 1448 } // namespace blink |
| OLD | NEW |